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