Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: glob qualifier '-' doesn't work correctly on dangling symlinks



On 2020-04-13 15:22:57 +0100, Stephane Chazelas wrote:
> 2020-04-13 01:38:45 +0200, Vincent Lefevre:
> [...]
> > > Well, as seen in the varying interpretations made by the various
> > > implementations, it is not that clear. How do you determine
> > > whether a file exists or not? What does "exist" mean?
> > 
> > You necessarily know it, or that's an error case (permission denied
> > or whatever). The behavior may not be clear in case of error, but
> > one can expect at least a non-zero exit status:
> [...]
> 
> Are you saying that EACCES is an "error" but ENOENT is not?

Yes, because getting EACCES implies that the system could not
determine whether the file exists or not. With ENOENT, the system
could determine that the file does not exist.

> How about ENOTDIR, ELOOP? None of /etc/passwd/foo, /etc/pesswd/foo,
> symloop/foo or /root/foo exist on my system, a stat() on a symlink
> to those would return ENOTDIR, ENOENT, ELOOP, EACCES. On which one
> should find -L return with a non-zero exit status?

ENOTDIR: in the symlink resolution, the system got a path prefix that
is not a directory, and this implies that the file cannot exist. Thus
this should not be regarded as an error (since the target file does
not exist, the file information and type is for the link itself).

ENOENT: Not an error, as this means that the target file does not
exist; so the file information and type is for the link itself.

ELOOP: This can imply two possibilities: either there is really a
loop, so that the symlink does not resolve to a file, or the number
of redirections is too large, but in this case, I would say that
this also means that the symlink does not resolve to a file because
a probably fixed system limit has been reached. Therefore it should
be fine to regard this as "not an error", like ENOTDIR and ENOENT.
I think that regarding this as an error would be bad because even
with sufficient permissions (e.g. as root) and resources, this could
make "find" fail every time, thus would not be very helpful.

EACCES: an error since the system could not determine whether
/root/foo exists or not, due to the lack of permissions.

ENOMEM would also be an error, assuming that this could occur on
any symlink.

> Which one(s) should find -L . -type l (or find . -xtype l)
> print?

/etc/passwd/foo
/etc/pesswd/foo
symloop/foo

(and I would expect an error message for /root/foo, such as
"Permission denied", in addition to a non-zero exit status).

> [...]
> >   -e  pathname
> >     True if pathname resolves to an existing directory entry.
> >     False if pathname cannot be resolved.
> > 
> > BTW, I don't know how zsh behaves on "[[ -e pathname ]]" in case of
> > error other than ENOENT in the pathname resolution, but this should
> > be documented (and ditto for the other conditional expressions).
> [...]
> 
> The mention of "directory entry" is misleading here. It's really
> about a "file" more than a "directory entry" as stat() gets you
> to the inode.

Bart replied. In any case, the inode here will necessarily correspond
to a directory entry (it will not be an orphaned inode), and with the
symlink resolution algorithm, you can also determine the directory in
question. So, nothing wrong here.

-- 
Vincent Lefèvre <vincent@xxxxxxxxxx> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)



Messages sorted by: Reverse Date, Date, Thread, Author