All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Blake <eblake@redhat.com>
To: "Pádraig Brady" <P@draigBrady.com>
Cc: Denys Vlasenko <vda.linux@googlemail.com>,
	Coreutils <coreutils@gnu.org>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	Christian Engelmayer <christian.engelmayer@frequentis.com>,
	Al Viro <viro@zeniv.linux.org.uk>
Subject: Re: rename("a", "b") would not always remove "a" on success. ?!!
Date: Fri, 28 Oct 2011 09:42:09 -0600	[thread overview]
Message-ID: <4EAACD51.5060703@redhat.com> (raw)
In-Reply-To: <4EAACAF0.4030401@draigBrady.com>

On 10/28/2011 09:32 AM, Pádraig Brady wrote:
>> http://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html
>>
>> 'If the old argument and the new argument resolve to either .... or different
>> directory entries for the same existing file, rename() shall return
>> successfully and perform no other action.'
>>
>> It's incredible they had audacity to put such nonsense into standard.
>>
>> The page says in "RATIONALE" section:
>>
>> 'The specification that if old and new refer to the same file is
>> intended to guarantee that:
>>
>> rename("x", "x");
>>
>> does not remove the file.'
>>
>> Why didn't they just explicitly say that they actually want THIS
>> particular case to work correctly, not OTHER cases to be fucked up?!

Because it is historical precedent, and changing it now would break 
software that has come to expect this behavior on hard links.

>>
>>
>> Anyway. My question is, does it really need to be implemented in Linux?
>> It looks bogus to me, and it basically requires any program
>> to contain a work-around for this case. For example, mv from util-linux
>> apparently already has a workaround:
>>
>> $ touch a; ln a b
>> $ strace mv a b
>> ...
>> stat64("b", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
>> lstat64("a", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
>> lstat64("b", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
>> geteuid32()                             = 0
>> unlink("a")                             = 0
>> close(0)                                = 0
>> close(1)                                = 0
>> close(2)                                = 0
>> exit_group(0)                           = ?
>
> mv is from coreutils BTW.
> Here is the related comment from the source:
>
> "Set *UNLINK_SRC if we've determined that the caller wants to do
> `rename (a, b)' where `a' and `b' are distinct hard links to the same
> file. In that case, the caller should try to unlink `a' and then return
> successfully.  Ideally, we wouldn't have to do that, and we'd be
> able to rely on rename to remove the source file.  However, POSIX
> mistakenly requires that such a rename call do *nothing* and return
> successfully."
>
> Perhaps it could be brought up as an issue with the standards guys?

We already have.  And POSIX 2008 already acted on that.  While you 
quoted rename(2) (which was intentionally not changed), you forgot to 
also read the POSIX wording on mv(1):

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/mv.html

2. If the source_file operand and destination path name the same 
existing file, then the destination path shall not be removed, and one 
of the following shall occur:

    a. No change is made to source_file, no error occurs, and no 
diagnostic is issued.
    b. No change is made to source_file, a diagnostic is issued to 
standard error identifying the two names, and the exit status is affected.
    c. If the source_file operand and destination path name distinct 
directory entries, then the source_file operand is removed, no error 
occurs, and no diagnostic is issued.

2a is the naive approach (using rename(2) semantics)
2b is the typical mv(1) approach (IIRC, both Solaris and BSD mv 
independently implemented this mode)
2c is the GNU coreutils approach (make mv(1) do what you meant, even 
though rename(2) is _required_ to do nothing)

Do NOT change the Linux kernel to "fix" rename(2); that will only cause 
more heartache by deviating from the standard.

-- 
Eric Blake   eblake@redhat.com    +1-801-349-2682
Libvirt virtualization library http://libvirt.org

  reply	other threads:[~2011-10-28 15:42 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-28 15:25 rename("a", "b") would not always remove "a" on success. ?!! Denys Vlasenko
2011-10-28 15:32 ` Pádraig Brady
2011-10-28 15:42   ` Eric Blake [this message]
2011-10-28 15:58     ` Eric Blake
2011-10-29  1:00     ` Denys Vlasenko
2011-10-29  1:19       ` richard -rw- weinberger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4EAACD51.5060703@redhat.com \
    --to=eblake@redhat.com \
    --cc=P@draigBrady.com \
    --cc=christian.engelmayer@frequentis.com \
    --cc=coreutils@gnu.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=vda.linux@googlemail.com \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.