Re: mv trailing slash warning
Eric Blake [EMAIL PROTECTED] wrote: According to Dr. David Alan Gilbert on 9/26/2005 11:17 AM: $ mkdir a b $ ln -s $PWD/a sym $ mv sym/ b mv: cannot move `sym/' to `b/sym': Not a directory Nod. Perhaps the warning needs a warning that it can't be relied on? No, POSIX requires rename(sym/, name) to move the directory, not the symlink, so the warning is accurate and should apply to all systems, whether or not their rename is conformant. You may also want to check what `type mv` prints, in case you have an alias in place that strips trailing slashes. As you can imagine, I find the POSIX-required behavior to be senseless. The above behavior of non-POSIX rename, seen on Linux-2.6.x, is fine. Now that Linux/glibc provides a sane rename function, I'm tempted to make mv work in the above manner on all systems rather than allowing the crazy move-pointed-to-directory behavior on systems with a technically-conforming rename. The wrapper will incur the expense of a syscall or two on losing systems when the first argument ends with `/'. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: mv trailing slash warning
Jim Meyering [EMAIL PROTECTED] writes: As you can imagine, I find the POSIX-required behavior to be senseless. Two things. First, I recall that you preferred the non-POSIX behavior because of file name completion issues. But because we agitated about this a while ago, Bash now does a better job with file name completion. For example, given this: mkdir dir ln -s dir symlink If I type mv sym[TAB], where [TAB] stands for a tab character, the screen then looks like this: mv symlink If I type another [TAB] it then looks like this: mv symlink/ so I'm given a signal from Bash that I have a symlink to a directory, and that it matters whether there's a trailing slash. In the old days this didn't happen, the intermediate step was missing, and so there was more of an argument that mv symlink/ target should ignore the slash. Nowadays, though, isn't that argument weaker? Second, I just read the POSIX spec and it seems to be a bit buggy http://www.opengroup.org/onlinepubs/009695399/functions/rename.html. The rationale says Renaming dot or dot-dot is prohibited but I can't see anything to that effect in the text itself. Furthermore, POSIX says that a pathname like abc/ must be resolved as if it were abc/. (see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_11) so arguably rename(abc/, def) must be handled like rename(abc/., def) and if renaming dot or dot-dot is prohibited (which I think it must be, even if it's omitted inadvertently from the standard) then this must fail. There's a similar issue with rmdir symlink/. It's not clear that rmdir (symlink/) should succeed, because pathname resolution indicates that it should be treated like rmdir (symlink/.) and this clearly must fail. Clearly it's a messy area. My kneejerk reaction is that I might prefer it if mv symlink/ foo and rmdir symlink/ always failed, if only because in a confusing situation like this it's often better to use the Hippocratic rule: first, do no harm. It would be easy to implement that rule: it wouldn't require any system calls at all, since we could simply reject all file names with trailing slashes. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: mv trailing slash warning
[cc-ing bash-completion maintainer] First, I recall that you preferred the non-POSIX behavior because of file name completion issues. But because we agitated about this a while ago, Bash now does a better job with file name completion. For example, given this: mkdir dir ln -s dir symlink If I type mv sym[TAB], where [TAB] stands for a tab character, the screen then looks like this: mv symlink If I type another [TAB] it then looks like this: mv symlink/ This assumes, of course, that you don't have 'set mark-symlinked-directories on' in your ~/.inputrc, at which point a single [TAB] completes the trailing slash. On the other hand, with the bash-completion package, it might make sense for programmable completion for mv, cp, and rm to omit the trailing slash in spite of the mark-symlinked-directories setting. The only argument against this is that there is no way to know whether the user really meant to move (or copy or delete) the symlink to a directory, vs. a file located in the directory, until they move on to the next word or hit Enter. This was the entire reason that mark-symlinked-directories exists in readline, and --strip-trailing-slashes exists as an option to mv and cp. On a related note, why don't rm and rmdir have a --strip-trailing-slashes option? so I'm given a signal from Bash that I have a symlink to a directory, and that it matters whether there's a trailing slash. Second, I just read the POSIX spec and it seems to be a bit buggy http://www.opengroup.org/onlinepubs/009695399/functions/rename.html. The rationale says Renaming dot or dot-dot is prohibited but I can't see anything to that effect in the text itself. Agreed - we should bring this up with the austin group. Something along the lines of this statement from rmdir(): If the path argument refers to a path whose final component is either dot or dot-dot, rmdir() shall fail. ... [EINVAL] The path argument contains a last component that is dot. Furthermore, POSIX says that a pathname like abc/ must be resolved as if it were abc/. (see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_1 1) so arguably rename(abc/, def) must be handled like rename(abc/., def) and if renaming dot or dot-dot is prohibited (which I think it must be, even if it's omitted inadvertently from the standard) then this must fail. I agree with your logic here on rename(2) needing to fail on a trailing slash if it is also supposed to fail on a trailing dot. But that doesn't necessarily mean that mv(1) need to fail on a trailing slash or dot. There's a similar issue with rmdir symlink/. It's not clear that rmdir (symlink/) should succeed, because pathname resolution indicates that it should be treated like rmdir (symlink/.) and this clearly must fail. Oops - cygwin has a bug in this regards: $ mkdir dir $ rmdir dir/. $ echo $? 0 $ ls dir ls: dir: No such file or directory Is it worth patching coreutils rm and rmdir to work around buggy systems that don't follow this POSIX restriction on rmdir()? (Meanwhile, I will try to get cygwin fixed.) Should we update the coreutils testsuite? My kneejerk reaction is that I might prefer it if mv symlink/ foo and rmdir symlink/ always failed, if only because in a confusing situation like this it's often better to use the Hippocratic rule: first, do no harm. It would be easy to implement that rule: it wouldn't require any system calls at all, since we could simply reject all file names with trailing slashes. You could probably convince me that your proposed approach of always rejecting an operation with a trailing slash is valid, as long as the error message gives a hint to the user on how to do what they wanted, and as long as --strip-trailing-slashes still worked. On the other hand, since 'mv symlink/ foo' invokes underspecified behavior in rename(2), maybe we can get away with deciding that mv(1) always behaves as --strip-trailing-slashes - is there anything in POSIX that would prohibit us from always stripping the trailing slash and acting on the symlink without an explicit option requesting that behavior? -- Eric Blake ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: mv trailing slash warning
Paul Eggert [EMAIL PROTECTED] wrote: Jim Meyering [EMAIL PROTECTED] writes: As you can imagine, I find the POSIX-required behavior to be senseless. Two things. First, I recall that you preferred the non-POSIX behavior because of file name completion issues. But because we agitated about this a That was indeed a motivator, since it made the commands with ambiguous syntax more likely. while ago, Bash now does a better job with file name completion. For example, given this: ... and so there was more of an argument that mv symlink/ target should ignore the slash. Nowadays, though, isn't that argument weaker? Even if bash fixes things to make this less likely, there's still plenty of room for user error and confusion, especially since less-seasoned users still use shells that cannot -- or are not configured to -- clean up the syntax of their commands. Personally, this hasn't affected me for some time (since I switched to zsh). zsh can be configured so that it completes the trailing slash in I type mv symliTAB zsh does this: mv symlink/ But the moment I type the space after the zsh-added `/', zsh removes that slash. If I type the slash, zsh leaves it. That said, I looked in some old command history logs and see hundreds of commands I typed (back before using zsh) including trailing slashes like this: mv dir/ new-name I know lots of people who would be very annoyed if they had to change habits or even just add an option via an alias to avoid failure in cases like those. Second, I just read the POSIX spec and it seems to be a bit buggy http://www.opengroup.org/onlinepubs/009695399/functions/rename.html. The rationale says Renaming dot or dot-dot is prohibited but I can't see anything to that effect in the text itself. Furthermore, POSIX says that a pathname like abc/ must be resolved as if it were abc/. (see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_11) so arguably rename(abc/, def) must be handled like rename(abc/., def) and if renaming dot or dot-dot is prohibited (which I think it must be, even if it's omitted inadvertently from the standard) then this must fail. There's a similar issue with rmdir symlink/. It's not clear that rmdir (symlink/) should succeed, because pathname resolution indicates that it should be treated like rmdir (symlink/.) and this clearly must fail. Clearly it's a messy area. My kneejerk reaction is that I might prefer it if mv symlink/ foo and rmdir symlink/ always failed, if only because in a confusing situation like this it's often better to use the Hippocratic rule: first, do no harm. It would be easy to implement that rule: it wouldn't require any system calls at all, since we could simply reject all file names with trailing slashes. IMHO, such a move [making mv fail for any source argument specified with a trailing slash] would `do harm' :-) albeit to people's sensibilities when GNU mv starts griping, not to their files. I think the wrapper-induced overhead of an extra lstat imposed on losing systems, but only for operands with a trailing slash, is bearable. This is one of those `would be nice' things. But I'm not in any big hurry, since Linux 2.6.x does it right. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: mv trailing slash warning
[EMAIL PROTECTED] (Eric Blake) writes: Why don't rm and rmdir have a --strip-trailing-slashes option? I'd guess because that option is an ugly hack and we'd rather that the problem went away we should bring this up with the austin group. Perhaps, but let's figure out what we want first. I agree with your logic here on rename(2) needing to fail on a trailing slash if it is also supposed to fail on a trailing dot. But that doesn't necessarily mean that mv(1) need to fail on a trailing slash or dot. But POSIX says mv a/ b does the equivalent of rename(a/, b). So if you agree with the logic, then mv a/ b must fail. Oops - cygwin has a bug in this regards: $ mkdir dir $ rmdir dir/. $ echo $? 0 $ ls dir ls: dir: No such file or directory Is it worth patching coreutils rm and rmdir to work around buggy systems that don't follow this POSIX restriction on rmdir()? Naah, let's just get cygwin fixed. On the other hand, since 'mv symlink/ foo' invokes underspecified behavior in rename(2), maybe we can get away with deciding that mv(1) always behaves as --strip-trailing-slashes POSIX may be underspecified, but it's not _that_ underspecified. :-) I think one could argue that mv symlink/ foo should rename the target of the symlink (which is what Solaris does), or that it should fail (which is what I'd mildly prefer); but I don't see a way to read POSIX to say that it allows mv to ignore the slash. Note that, by this argument, mv dir/ foo should fail even if dir/ is an ordinary directory and is not a symlink. So it'd be kind of a big change. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: mv trailing slash warning
[EMAIL PROTECTED] (Eric Blake) wrote: As you can imagine, I find the POSIX-required behavior to be senseless. The above behavior of non-POSIX rename, seen on Linux-2.6.x, is fine. Now that Linux/glibc provides a sane rename function, I'm tempted to make mv work in the above manner on all systems rather than allowing the crazy move-pointed-to-directory behavior on systems with a technically-conforming rename. The wrapper will incur the expense of a syscall or two on losing systems when the first argument ends with `/'. If you do that, you need to make sure POSIXLY_CORRECT still gets the POSIX behavior of move-pointed-to-directory. But Not if I deem that behavior senseless :-) Can you imagine any real user (non-standards-weenie) *wanting* or even expecting that behavior? The few people I've shown that example to in person have always looked a little slack-jawed and expressed dismay that such silly behavior is mandated. wasn't this the reason that --strip-trailing-slashes was created as an option? That way, a user can do alias mv='mv --strip-trailing-slashes' and get the sane behavior of always moving the symlink, not the pointed-to-directory, regardless of whether rename() is conformant or not, and regardless of whether their shell's tab-completion puts slashes on symlinks-to-directories. Right. But as long as Linux's rename had the unwanted behavior, I was unwilling to impose the overhead of a wrapper. Now that constraint is removed. Meanwhile, since you think that the POSIX definition of rename() is insane, try filing an aardvark to allow an implementation-defined choice between moving the symlink/moving the directory, rather than the current mandated semantics of moving the directory. That way, Linux 2.6.x would still be able to comply to POSIX with what you term to be saner semantics (personally, I like the POSIX-mandated semantics, as it provides a consistent way to choose between operating on the symlink vs. operating on what it points to by the presence of the trailing slash, and it is not just rename() that is affected by POSIX semantics). Or you could file an aardvark on mv(1) to allow an implementation to always strip trailing slashes before calling rename(). I don't want to give myself that kind of work right now. Besides, I don't lose sleep if a GNU tool or two deviate from POSIX on corner cases like this. One way or another, we'll all converge, eventually. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: mv trailing slash warning
On a related note, why don't rm and rmdir have a --strip-trailing-slashes option? Because as far as I know, there is no need. Do you know of a system where `rmdir symlink/' removes only the referent of the symlink? Yes, cygwin (but again, that goes back to the rmdir(2) bug in cygwin that I have just reported to the cygwin maintainers): $ mkdir a $ ln -s a b $ rmdir b/ $ ls -F a b ls: a: No such file or directory b@ Whereas on sane systems (for example, Solaris 8): $ mkdir a $ ln -s a b $ rmdir b/ rmdir: directory b/: Path component not a directory $ rmdir b/. rmdir: directory b/.: Can't remove current directory or .. By Paul's argument, both uses should have failed with EINVAL, since POSIX requires resolving symlink/ as symlink/., and requires rmdir(symlink/. to fail with EINVAL. Solaris 8 returned ENOTDIR in the first case, so it appears they stripped the trailing slash (and their error message leaves something to be desired in accuracy in the second case). But at least it reliably failed instead of removing a. I don't have access to other systems to see what other behaviors might exist. Is it worth patching coreutils rm and rmdir to work around buggy systems that don't follow this POSIX restriction on rmdir()? (Meanwhile, I will try to get cygwin fixed.) Should we update the coreutils testsuite? It depends a whole lot on how invasive or complicated the patch is. Ideally, it wouldn't change anything in src/*.c at all. If cygwin doesn't get patched, it sounds like a gnulib module to replace rmdir() is all that would be needed. Something like this untested snippet (it would need to be cleaned up for corner cases like , /, ., but you get the picture): int rpl_rmdir(const char* name) { int len = strlen (name); if (name[len - 1] == '/' || (name[len - 1] == '.' (name[len - 2] == '/' || (name[len - 2] == '.' name[len - 3] == '/' { errno = EINVAL; return -1; } return rmdir (name); } -- Eric Blake ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: mv trailing slash warning
Jim Meyering [EMAIL PROTECTED] writes: Do you know of a system where `rmdir symlink/' removes only the referent of the symlink? Lots of systems do that, I expect. Solaris 10 does, for example. This is either with Solaris rmdir or coreutils 5.3.0 rmdir. I wouldn't be surprised if core commands other than mv and rmdir are affected by this issue as well. rm and ln come to mind, though I haven't tested them. Here's a transcript on Solaris 10 (sparc) with coreutils 5.3.0: 1018-otter $ ls -l total 2 drwxrwxr-x 2 eggert faculty 512 2005-09-28 15:18 dir lrwxrwxrwx 1 eggert faculty 3 2005-09-28 15:18 symlink - dir 1019-otter $ rmdir symlink/ 1020-otter $ ls -l total 1 lrwxrwxrwx 1 eggert faculty 3 2005-09-28 15:18 symlink - dir ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: mv trailing slash warning
Jim Meyering [EMAIL PROTECTED] writes: I think the wrapper-induced overhead of an extra lstat imposed on losing systems, but only for operands with a trailing slash, is bearable. This is one of those `would be nice' things. But I'm not in any big hurry, since Linux 2.6.x does it right. Yes, I wouldn't be in any hurry either. Come to think of it, how about if we just stick to the current approach, and let 'mv' use the system rename() function and do whatever rename() does? Advantages of the current approach: * Easier to implement and maintain. * Solaris folks used to Solaris mv's behavior won't be surprised by GNU mv. * GNU mv conforms to POSIX, on POSIX-conforming hosts. (On non-POSIX hosts all bets are off anyway. :-) Disadvantages: * GNU mv behaves differently on different hosts. Similarly for rmdir and rmdir(), etc. I suppose either way, the eocumentation needs to explain the issue better. (Arrgh.) ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: mv trailing slash warning
On a related note, why don't rm and rmdir have a --strip-trailing-slashes option? Because as far as I know, there is no need. Do you know of a system where `rmdir symlink/' removes only the referent of the symlink? By a strict reading of http://www.opengroup.org/onlinepubs/009695399/utilities/rm.html, 'rm -R symlink/' should empty the referrant, then fail! step 0: the command line does not end in . step 1: symlink/ exists step 2: 'symlink/' is of type directory ('symlink', on the other hand, is of type symlink); this is the recursion, ending with the referrant being emptied, and symlink and symlink/ still existing step 3: 'symlink/' is a directory step 4: call rmdir(symlink/), which should fail with EINVAL But no implementation of rm(1) that I am aware of does this; they all unlink symlink and call it quits, leaving the referrant (and its contents) alone. We really do need to clean this up with the austin group; surely they intended to document historical behavior. -- Eric Blake ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: mv trailing slash warning
* Jim Meyering ([EMAIL PROTECTED]) wrote: $ mkdir a b $ ln -s $PWD/a sym $ mv sym/ b mv: cannot move `sym/' to `b/sym': Not a directory The 'mv' is straight out of recent cvs. I'm in an ext3 filesystem on Linux (Ubuntu). Am I misunderstanding something about that warning or is this a bug? It depends on the semantics of the rename syscall. And those semantics vary from system to system. On older linux systems (probably 2.4.x, certainly 2.2.20, which I've just tested) your mv command renames `a' to b/sym. OK, as far as I can tell on the 2.6.x machines I've tried it on it doesn't. Losing systems probably deserve a configure-time test and a rename wrapper to correct for the unexpected behavior. Nod. Perhaps the warning needs a warning that it can't be relied on? Dave -- -Open up your eyes, open up your mind, open up your code --- / Dr. David Alan Gilbert| Running GNU/Linux on Alpha,68K| Happy \ \ gro.gilbert @ treblig.org | MIPS,x86,ARM,SPARC,PPC HPPA | In Hex / \ _|_ http://www.treblig.org |___/ ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: mv trailing slash warning
Dr. David Alan Gilbert [EMAIL PROTECTED] wrote: In the info pages for 'mv' is the following statement: --- _Warning_: If you try to move a symlink that points to a directory, and you specify the symlink with a trailing slash, then `mv' doesn't move the symlink but instead moves the directory referenced by the symlink. *Note Trailing slashes::. --- ... $ mkdir a b $ ln -s $PWD/a sym $ mv sym/ b mv: cannot move `sym/' to `b/sym': Not a directory The 'mv' is straight out of recent cvs. I'm in an ext3 filesystem on Linux (Ubuntu). Am I misunderstanding something about that warning or is this a bug? It depends on the semantics of the rename syscall. And those semantics vary from system to system. On older linux systems (probably 2.4.x, certainly 2.2.20, which I've just tested) your mv command renames `a' to b/sym. Losing systems probably deserve a configure-time test and a rename wrapper to correct for the unexpected behavior. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils