On 2007-08-20 23:57:45 -0600, Bob Proulx wrote:
> Vincent Lefevre wrote:
> > Bob Proulx wrote:
> > > The touch command follows symlinks because generally everything
> > > follows symlinks.  The commands that do not follow symlinks are the
> > > exceptions to that rule.
> > 
> > I'd say this is the opposite for commands that operate on meta-data
> > (such as 'touch').
> 
> I wanted to trim my quote but I was not sure to what part you were
> referring to as being the opposite.  I did not understand the meaning
> of your statement.  Sorry.

I meant that the commands that operate on meta-data don't follow
the symbolic links in general, and 'touch' is an exception.

> Touch simply open()s the file or calls utime{,s}() on the file.

I don't understand. The utime(2) man page says:

    int utime(const char *filename, const struct utimbuf *buf);
    int utimes(const char *filename, const struct timeval times[2]);

i.e. these functions take a filename (string) in argument, not a
FILE *, not a file descriptor either. So, I don't see why 'touch'
needs to open the file.

> The underlying filesystem then follows the symlink as expected. At
> least as I expect it to do anyway. :-)
> 
> A symlink can never be an open file.

I agree. But my point is that 'touch' doesn't need to open a file
(as I said above). Also note that the end user (who reads the 'touch'
documentation) doesn't necessarily know how 'touch' is implemented
(and shouldn't need to).

> > > The rm command is not an exception here because rm operates on
> > > symbolic links normally.
> > 
> > It is an exception as it doesn't follow the symbolic links.
> 
> But in the case of removing file arguments there is no meaning to
> following a symlink.  The symlink itself is the file argument and it
> is removed.  Since rm is really performing a directory operation the
> directory either includes the file argument and it is removed from the
> directory or it does not and an error occurs.

That's true that it doesn't modify the inode if there are additional
links.

> > Ditto for chown and chgrp. I think that most commands that operate
> > on meta-data are exceptions!
> 
> Yes.  So?  Other commands are the majority such as cat, grep, sed,
> cut, paste, join, and so on.

All these commands read or write file *contents*, basically doing an
open.

> The number of commands that operate on the inode are a smaller set.
> I think this means that we are in agreement here. (Not sure though.)

Yes, this is *exactly* what I mean: 'touch' is part of the few commands
that operate on the inode, thus it should be documented concerning the
behavior on the symlinks (since amongst these commands, the behavior
on the symlinks is not always the same, and in general, symlinks are
not dereferenced).

> > vin:~> touch -c link
> 
> This calls utimes(2) on link, which returns ENOENT (No such file or
> directory), indicating that the file does not exist.  Because the -c
> option was given the file is not created if it does not exist and a
> successful exit code is returned.

But it would be more logical to return a non-zero exit status, as
the 'touch' could not be performed. The -c option means that the
file is not created (if it doesn't exist), no more. For instance,
'touch -c blah/cd' can return the error

touch: setting times of `blah/cd': Permission denied

though blah/cd doesn't exist. That's inconsistent.

> > vin:~> chmod 644 link
> 
> That does seem to be incorrect.  It can't succeed and so to me seems
> like it should fail.  But I have not looked at the history.  I will
> investigate this one.

OK.

> > vin:~> cat link
> > cat: link: No such file or directory
> 
> The open(2) fails, is reported, and a error exit code is returned.

The exit status is the status on the *command*, not on some internal
system call. The 'cat' could not be performed, therefore a non-zero
exit status is return. The 'touch -c link' could not be performed,
therefore it should have returned a non-zero exit status. Similarly,
the noclobber zsh option also allows to avoid file creation when
using '>>':

vin% setopt noclobber
vin% echo ab >> cd || echo fail
zsh: no such file or directory: cd
fail
vin%

As you can see, a non-zero exit status was returned, because the
command could not be performed.

> > Isn't that confusing?
> 
> The chmod handling of dangling symlinks is confusing and I think
> deserves a closer look as to why it is doing what it is doing.  All
> else follows normally and seems perfectly reasonable to me.  Except
> for the chmod case above don't you agree?

No. I can see 3 classes of commands that operate on files/inodes
(I don't include those that operate on directory entries such as
'rm', though their argument are filenames):
  1. Those that follow symbolic links because it would make no sense
     if they were not: 'chmod' and all the commands that operate on
     the file contents.
  2. Those that operate on meta-data and follow symbolic links though
     both the symbolic link and the file have such meta-data (visible
     with 'ls -l'): 'touch'.
  3. Those that operate on meta-data and do not follow symbolic links
     (by default): 'chown', 'chgrp', 'stat'.

Did I miss any command?

For commands of class 1, it is pretty clear, i.e. no need to document
what they do on symlinks. Now, the problem is: commands of class 2 vs
commands of class 3. As you can see, 'touch' seems to be the exception.

Note: if symbolic links get visible permissions on some system, the
behavior of 'chmod' on symbolic links should be documented.

> > Only commands that operate on meta-data (i.e. not the file contents[*])
> > are concerned. I don't think that would be too much.
> 
> Agreed.  But that would mean that touch would not need to mention
> symlinks.  Right?

Why?

> There is no way to update the times on a symlink and therefore no
> option available in touch to avoid passing through the symlink.

How does the end user know that? I recall that 'ls -l' shows different
timestamps, so that it is not obvious (contrary to 'chmod').

> > > Actually FILE in the above refers to the use of FILE as a command line
> > > argument to the touch command as noted in the synopsis.  It could say
> > > the following not using FILE and also be correct:
> > > 
> > >        touch [OPTION]... FOO...
> > > 
> > >     Any FOO that does not exist is created empty.
> > > 
> > >     A FOO of `-' causes `touch' to change the times of the file
> > >   associated with standard output.
> > 
> > But again, the term "FOO" would be used with two different meanings.
> 
> No.  It is not.  We are still out of sync somewhere here.  FOO means
> the literal three characters F, O, O, which appear on the command
> synopsis line as a program argument.

Oh, that's confusing. Manuals generally use a different typesetting
(or markup) to distinguish literals and replaceable text.

-- 
Vincent Lefèvre <[EMAIL PROTECTED]> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Reply via email to