Re: mv trailing slash warning

2005-09-28 Thread Jim Meyering
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

2005-09-28 Thread Paul Eggert
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

2005-09-28 Thread Eric Blake
[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

2005-09-28 Thread Jim Meyering
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

2005-09-28 Thread Paul Eggert
[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

2005-09-28 Thread Jim Meyering
[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

2005-09-28 Thread Eric Blake
  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

2005-09-28 Thread Paul Eggert
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

2005-09-28 Thread Paul Eggert
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

2005-09-28 Thread Eric Blake
  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

2005-09-26 Thread Dr. David Alan Gilbert
* 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

2005-09-25 Thread Jim Meyering
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