Re: "readlink -f foo" fails if the target of foo does not exist

From:

Jim Meyering

Subject:

Re: "readlink -f foo" fails if the target of foo does not exist

Date:

Sat, 10 Jan 2004 15:32:05 +0100

Paul Eggert <address@hidden> wrote:
> Jim Meyering <address@hidden> writes:
>
>> So here's a better spec:
>>
>> If canonicalize_file_name (FILE) succeeds, work exactly as now.
>> else if lstat (FILE) succeeds,
>> linkname = readlink (FILE)
>> if linkname starts with `/', print linkname
>> otherwise, print $(readlink -f $(dirname FILE))/linkname
>> else, work exactly as now.
>
> Hmm, the above algorithm doesn't canonicalize linkname. If linkname
> contains "." or ".." components, shouldn't they be canonicalized out?
Yes. Thanks!
> For example, linkname might be "../bar", and if so the above algorithm
> would print /a/b/c/../bar when it should print /a/b/bar.
>
> Another possibility is that linkname could refer to symbolic links.
> For example, if linkname is "s/x" where s is a symbolic link to "/",
> and "/x" does not exist, then you should print "/x", not "/a/b/c/s/x".
>
> Canonicalizing linkname as described above would result in a different
> file name FILE1 which couldn't be printed immediately, since it you
> would then have to fed back into the above algorithm. Unless the file
> system was mutating under you, presumably canonicalize_file_name
> (FILE1) would fail for the same reason that canonicalize_file_name
> (FILE) failed. However, lstat (FILE1) might succeed, or might fail.
> If it fails, you're done: if it succeeds and if readlink (FILE1) gives
> you an absolute link, you're done as well; but if readlink (FILE1)
> gives you a relative link, you have to construct a new name FILE2 and
> start over again. So this whole process might loop.
Good points.
In case of a cycle, it'd have to detect it and fail, of course.