Subject: bug#13447: ln "" foo gives misleading error message

From: Joerg Schilling <[email-masked]>
Date: Wed, 16 Jan 2013 12:07:27 +0100

Eric Blake <[email-masked]> wrote:

> [adding the Austin Group]
>
> On 01/15/2013 02:58 AM, Jim Meyering wrote:
>
> >>> That Solaris behavior is contrary to POSIX 2008
> >>> http://pubs.opengroup.org/onlinepubs/9699919799/functions/symlink.html
> >>
> >> Where does it say this?  I read it through in detail but I didn't see
> >> that it required a diagnostic to be emitted in the case that value is
> >> am empty string.  What did I miss?
> > 
> > Oh!  You're right.  Thanks for pointing that out.
> > It's only the source (2nd argument) to symlink that may not
> > be the empty string.
>
> I also checked POSIX 2008 TC1 (in the middle of ratification process),
> and while it altered the wording, it still mentions only path2:
>
> On Page: 2058 Line: 65095 Section: symlink()
> In the ERRORS section, change the [ENOENT] error from:
> [ENOENT] A component of path2 does not name an existing file or
> path2 is an empty string.
> to:
> [ENOENT] A component of the path prefix of path2 does not name an
> existing file or path2 is an empty string.
> [ENOENT] or [ENOTDIR]
> The path2 argument contains at least one non-<slash> character and ends
> with one or more trailing <slash> characters. If path2 names an existing
> file, an [ENOENT] error shall not occur.
> Rationale: Austin Group Defect Report(s) applied: 146,428,436.
> See http://austingroupbugs.net/view.php?id=146
> See http://austingroupbugs.net/view.php?id=428
> See http://austingroupbugs.net/view.php?id=436
>
> What do others on the Austin Group think about an empty string for path1
> in symlink()?  Current Linux rejects the symlink() call with ENOENT;
> FreeBSD 8.2 allows it but refuses to resolve the symlink ("ln -s '' a &&
> ls a/" reports ENOENT); Solaris 10 allows it and resolves the symlink as
> though it were '.' ("ln -s '' a && ls a/" reports the current directory
> contents).

I believe that symlink("", "foo") should be valid according to
http://pubs.opengroup.org/onlinepubs/9699919799/functions/symlink.html

On the other side, Solaris (correctly) returns ENOENT for open("", O_RDONLY);
so the question is how symlink processing should be done in the kernel. 

If the symlink target is to be treated as a list of path name components, 
I would expect ENOENT with an attempt to open() or stat() "a/".

If the symlink target is treated as a string that is concatenated to the 
previous path, Solaris could be seen as correct.

Solaris replaces an empty symlink target ("") by "." before replacing the 
current path name component in the path currently being processed by the 
symlink target string before continuing with the path processing on the 
resulting path.

Jörg

-- 
 EMail:[email-masked] (home) Jörg Schilling D-13353 Berlin
       [email-masked]                (uni)  
       [email-masked] (work) Blog: http://schily.blogspot.com/
 URL:  http://cdrecord.berlios.de/private/ ftp://ftp.berlios.de/pub/schily