[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.
Jim
[*] It's not hard to work around in mv.c, but that would be wrong:
checking *before* calling rename would introduce a race condition.