summaryrefslogtreecommitdiff
path: root/src/ls.c
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2012-05-10 19:43:00 +0200
committerJim Meyering <meyering@redhat.com>2012-05-12 16:19:38 +0200
commit6124a3842dfa8484b52e067a8ab8105c3875a4f7 (patch)
treeb7047bc1393246d26c7f4af2bcf9d3622e56dd12 /src/ls.c
parente438a0e8581cfd5ce3df0f37ba46163f725d0bb0 (diff)
downloadcoreutils-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/ls.c')
-rw-r--r--src/ls.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/ls.c b/src/ls.c
index 397e4ea92..9494ae919 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -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;
}