On Tue, Apr 04, 2017 at 05:03:26PM -0500, Scott Cheloha wrote:
> > On Apr 4, 2017, at 4:46 PM, Nicholas Marriott <[email protected]> 
> > wrote:
> > 
> > readlink is explicitly documented to silently exit 1 if run without -f,
> > and GNU readlink behaves the same way. I doubt that should change.
> 
> Yeah, I saw that.  I (incorrectly, I guess?) interpreted it to mean
> "does not print anything on the standard output."
> 
> My think is -- and maybe I'm being nitpicky, but -- the documentation
> says:
> 
> > If the -f option is not specified and readlink is invoked with an
> > argument other than the pathname of a symbolic link, it exits with
> > a nonzero exit code without printing anything.
> 
> In the current code, however, you could have insufficient permissions
> for a part of the path (EPERM), or an I/O failure (EIO), but otherwise
> specify a valid symbolic link, and still get the described behavior,
> which seems wrong to me.
> 
> If the documented "say nothing and exit 1" behavior when the target
> is not a symbolic link is sacred, then maybe this snippet is better:

There are likely to be existing scripts that rely on this behaviour.

> 
>       if (fflag) {
>               if (realpath(argv[0], buf) == NULL)
>                       err(1, "%s", argv[0]);
>       } else {
> -             if ((n = readlink(argv[0], buf, sizeof buf-1)) < 0)
> -                     exit(1);
> +             if ((n = readlink(argv[0], buf, sizeof(buf) - 1)) == -1) {
> +                     if (errno != EINVAL)
> +                             warn("%s", argv[0]);

You will definitely also need to check for at least ENOENT and ENOTDIR,
possibly others too.

I think it would be better not to change the behaviour, except possibly
for ENAMETOOLONG.

> +                     return 1;
> +             }
>               buf[n] = '\0';
>       }
> 
> That way you still say nothing if the issue is, in fact, that your target
> isn't a symbolic link, but you point out any other errors.
> 
> --
> Scott Cheloha

Reply via email to