Jim Meyering wrote: > Jim Meyering wrote: >> Mike Frysinger wrote: >>> coreutils-8.16 works fine (confirmed), and i don't recall seeing this bug >>> before, so looks like a regression with 8.17 >>> >>> easy to show: >>> $ sudo ln -s dev /foo >>> $ ls --color=auto / >>> ... foo wrongly shows up in blinky text indicating it's a broken symlink ... >>> $ ls --color=auto /. >>> ... foo correctly shows up with normal coloring indicating it's a symlink >>> ... >>> $ cd / ; ls --color=auto >>> ... foo correctly shows up with normal coloring indicating it's a symlink >>> ... >>> -mike >> >> Rats. >> That bug was introduced by my clean-up. >> Here's the probable fix. >> Thanks for the report! >> >> diff --git a/src/ls.c b/src/ls.c >> index 397e4ea..b548382 100644 >> --- a/src/ls.c >> +++ b/src/ls.c >> @@ -3213,7 +3213,8 @@ 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); >> + bool prefix_ends_in_slash = ISSLASH (name[prefix_len - 1]); >> + stpcpy (stpncpy (p, name, prefix_len + !prefix_ends_in_slash), linkname); > > While the above fixes your problem, it fails to > solve the problem when running e.g., > > mkdir -p d/b; (cd d; ln -s b link); ls --color d
Actually the above is fine after all -- and it uses less memory than the patch below. I must have been testing something else. > (i.e., with a single-component base directory name and a symlink > to a relative name it would still color "link" as if it were dangling) > > This fixes both: > > diff --git a/src/ls.c b/src/ls.c > index 397e4ea..93a3338 100644 > --- a/src/ls.c > +++ b/src/ls.c > @@ -3206,14 +3206,9 @@ make_link_name (char const *name, char const *linkname) > if (IS_ABSOLUTE_FILE_NAME (linkname)) > return xstrdup (linkname); > > - /* The link is to a relative name. Prepend any leading directory > - in 'name' to the link name. */ > - size_t prefix_len = dir_len (name); > - if (prefix_len == 0) > - return xstrdup (linkname); > - > - char *p = xmalloc (prefix_len + 1 + strlen (linkname) + 1); > - stpcpy (stpncpy (p, name, prefix_len + 1), linkname); > + char *d = dir_name (name); > + char *p = file_name_concat (d, linkname, NULL); > + free (d); > return p; > }
