diff options
author | Jim Meyering <meyering@redhat.com> | 2012-05-10 19:43:00 +0200 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2012-05-12 16:19:38 +0200 |
commit | 6124a3842dfa8484b52e067a8ab8105c3875a4f7 (patch) | |
tree | b7047bc1393246d26c7f4af2bcf9d3622e56dd12 /src | |
parent | e438a0e8581cfd5ce3df0f37ba46163f725d0bb0 (diff) | |
download | coreutils-6124a3842dfa8484b52e067a8ab8105c3875a4f7.tar.xz |
ls: color each symlink-to-relative-name in / properly
In order for ls --color to color each symlink, it must form the name
of each referent and then stat it to see if the link is dangling, to
a directory, to a file, etc. When the symlink is to a relative name,
ls must concatenate the starting directory name and that relative name.
When, in addition, the starting directory was "/" or "/some-name",
the result was ill-formed, and the subsequent stat would usually fail,
making the caller color it as a dangling symlink.
* src/ls.c (make_link_name): Don't botch the case in which
dir_name(NAME) == "/" and LINKNAME is relative.
* tests/ls/root-rel-symlink-color: New file. Test for the above.
* tests/Makefile.am (TESTS): Add it.
* NEWS (Bug fixes): Mention it.
Reported by Mike Frysinger in http://bugs.gnu.org/11453
Bug introduced by commit v8.16-23-gbcb9078.
Diffstat (limited to 'src')
-rw-r--r-- | src/ls.c | 9 |
1 files changed, 8 insertions, 1 deletions
@@ -3213,7 +3213,14 @@ make_link_name (char const *name, char const *linkname) return xstrdup (linkname); char *p = xmalloc (prefix_len + 1 + strlen (linkname) + 1); - stpcpy (stpncpy (p, name, prefix_len + 1), linkname); + + /* PREFIX_LEN usually specifies a string not ending in slash. + In that case, extend it by one, since the next byte *is* a slash. + Otherwise, the prefix is "/", so leave the length unchanged. */ + if ( ! ISSLASH (name[prefix_len - 1])) + ++prefix_len; + + stpcpy (stpncpy (p, name, prefix_len), linkname); return p; } |