[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bug fix: mv and 'cp -r' no longer fail when ...

From: Jim Meyering
Subject: Re: bug fix: mv and 'cp -r' no longer fail when ...
Date: Wed, 13 Sep 2006 13:47:44 +0200

Jim Meyering <address@hidden> wrote:
> 2006-09-08  Jim Meyering  <address@hidden>
>       mv and "cp -r" no longer fail when invoked with two arguments
>       where the first one names a directory and the second name ends in
>       a slash and doesn't exist.  E.g., "mv dir B/", for nonexistent B,
>       now succeeds, once more. This reverts part of the 2004-06-27
>       change for 5.3.0.

FYI, there is a little portability fallout from the above change.

Now, "mv dir B/" fails on NetBSD 1.6, because its underlying
rename syscall interprets the trailing destination slash (when the
destination doesn't exist) differently than the rename on recent
Linux and Solaris systems.

    netbsd$ rm -rf a b; mkdir a; perl -e 'rename "a", "b/" or die "$!\n"'
    No such file or directory
    [Exit 2]

The mv command and the above rename example work just fine on Linux
and Solaris.

I think I'll have to add a rename wrapper for systems like NetBSD that
work this way.[*]  It won't be expensive, since the wrapper will do extra
work only if the rename syscall fails with ENOENT and the destination
name has a trailing slash.  The "extra work" is to repeat the rename
call using a stripped destination name when lstat calls tell us that the
source argument specifies a directory and the destination doesn't exist.

Note that this is a separate issue from the one about trailing slashes
on rename's *source* operand.

One could argue that the NetBSD rename semantics are closer to what POSIX
intended, since POSIX's "Pathname Resolution" section says that a name
specified with a trailing slash (e.g., "foo/") shall be resolved as if
the name had an appended "." (e.g., "foo/.").  However, long-standing
practice at the command line level is to ignore trailing destination
slashes, at least when the source is a directory and the destination
does not exist or is a directory.

Note that technically, mv is supposed to defer to the underlying
"rename" syscall for most of its semantics.  Here, I'm considering a
rename wrapper, to be used only on NetBSD-1.6-like systems, so that GNU
mv is more consistent.


[*] It's not hard to work around in mv.c, but that would be wrong:
checking *before* calling rename would introduce a race condition.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]