Subject: Re: "Renaming: permission denied" file-error in Windows

From: Eli Zaretskii <[email-masked]>
Date: Sun, 25 Dec 2011 04:39:18 -0500

[Redirected to the bug tracker, to keep the entire discussion archived.]

> Date: Sun, 25 Dec 2011 09:33:34 +0200
> From: LynX <[email-masked]>
> CC: [email-masked], [email-masked]
> 
> I've opened a bug report here:
> 
> 10284: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=10284

Thanks.

>     result = rename (temp, newname);
> 
>     if (result < 0
> -      && errno == EEXIST
> -      && _chmod (newname, 0666) == 0
> -      && _unlink (newname) == 0)
> -    result = rename (temp, newname);
> +      && errno == EEXIST)
> +    {
> +      if (_chmod (newname, 0666) != 0)
> +	return result;
> +      if (_unlink (newname) != 0)
> +	return result;
> +      result = rename (temp, newname);
> +    }
> +
> +  /* The implementation of `rename' on Windows does not return
> +     errno = EXDEV when you are moving a directory to a different
> +     storage device (ex. logical disk). It returns EACCES
> +     instead. So here we handle such situations and return EXDEV.   */
> +
> +  if (result < 0
> +      && errno == EACCES
> +      && newname_dev != oldname_dev)
> +    errno = EXDEV;

This first removes the target, and only then compares the device
numbers.  Wouldn't it be better to do it the other way around, at
least when the target is a directory?  That way, the target is left
intact if the caller doesn't want to copy over the target, and also
the filesystem is left in the same state as on Posix hosts in this
case, i.e. the contract of `rename' is preserved on all systems.

Thanks for working on this.