summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2011-10-01 01:47:53 +0100
committerPádraig Brady <P@draigBrady.com>2011-10-01 02:15:12 +0100
commit84457c491e775f664a1c33274cd2c5acadb5be73 (patch)
tree983d17c1a92e99ee1c686e28c468217501f6c5b7
parent4f38e9f24971762540da9d5457dfa9e5e03d53ee (diff)
downloadcoreutils-84457c491e775f664a1c33274cd2c5acadb5be73.tar.xz
ls: fix output of dangling symlinks colored as target
This is related to commit b7f2b51c, 2010-01-01, "ls: fix color of broken symlinks colored as target" which didn't handle the --dereference case. The simplest way to reproduce the resultant erroneous "argetm" is as follows: $ ln -s /no-such dangle $ env LS_COLORS=ln=target ls --dereference --color ls: cannot access dangle: No such file or directory argetmdangle This is also an issue with the `tree` utility, reported here: http://bugs.debian.org/586765 * src/ls.c (print_color_indicator): Move the handling of 'ln=target' in $LS_COLORS (color_symlink_as_referent == true) to a higher scope, to handle all cases where type == C_LINK. * tests/misc/ls-misc: Add a test case for the specific issue, and 2 further test cases to verify other code paths in this area. Reported by Jason Glassey.
-rw-r--r--src/ls.c13
-rwxr-xr-xtests/misc/ls-misc41
2 files changed, 50 insertions, 4 deletions
diff --git a/src/ls.c b/src/ls.c
index c1b19188c..1b0c250d7 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -4203,10 +4203,7 @@ print_color_indicator (const struct fileinfo *f, bool symlink_target)
type = C_STICKY;
}
else if (S_ISLNK (mode))
- type = ((!linkok
- && (color_symlink_as_referent
- || color_indicator[C_ORPHAN].string))
- ? C_ORPHAN : C_LINK);
+ type = C_LINK;
else if (S_ISFIFO (mode))
type = C_FIFO;
else if (S_ISSOCK (mode))
@@ -4241,6 +4238,14 @@ print_color_indicator (const struct fileinfo *f, bool symlink_target)
}
}
+ /* Adjust the color for orphaned symlinks. */
+ if (type == C_LINK && !linkok)
+ {
+ if (color_symlink_as_referent
+ || color_indicator[C_ORPHAN].string)
+ type = C_ORPHAN;
+ }
+
{
const struct bin_str *const s
= ext ? &(ext->seq) : &color_indicator[type];
diff --git a/tests/misc/ls-misc b/tests/misc/ls-misc
index 8b356d4ae..b159bbffd 100755
--- a/tests/misc/ls-misc
+++ b/tests/misc/ls-misc
@@ -223,6 +223,47 @@ my @Tests =
restore_ls_colors; }},
],
+ # Test for a bug fixed after coreutils-8.13
+ # where 'argetm' was errenously printed for dangling links
+ # when ln=target was used in LS_COLORS
+ ['sl-dangle6', '-L --color=always d',
+ {OUT => "s\n"},
+ {PRE => sub {mkdir 'd',0755 or die "d: $!\n";
+ symlink 'dangle', 'd/s' or die "d/s: $!\n";
+ push_ls_colors('ln=target')
+ }},
+ {POST => sub {unlink 'd/s' or die "d/s: $!\n";
+ rmdir 'd' or die "d: $!\n";
+ restore_ls_colors; }},
+ {ERR => "ls: cannot access d/s: No such file or directory\n"},
+ {EXIT => 1}
+ ],
+ # Related to the above fix, is this case where
+ # the code simulates "linkok". In this case "linkmode"
+ # should always be zero, and hence not trigger any
+ # issues with type being set to C_LINK
+ ['sl-dangle7', '--color=always d',
+ {OUT => "$e\e[ms$e\n"},
+ {PRE => sub {mkdir 'd',0755 or die "d: $!\n";
+ symlink 'dangle', 'd/s' or die "d/s: $!\n";
+ push_ls_colors('ln=target:or=:ex=:')
+ }},
+ {POST => sub {unlink 'd/s' or die "d/s: $!\n";
+ rmdir 'd' or die "d: $!\n";
+ restore_ls_colors; }},
+ ],
+ # Another case with simulated "linkok", that does
+ # actually use the value of 'ln' from $LS_COLORS.
+ # This path is not taken though when 'ln=target'.
+ ['sl-dangle8', '--color=always s',
+ {OUT => "$e\e[1;36ms$e\n"},
+ {PRE => sub {symlink 'dangle', 's' or die "s: $!\n";
+ push_ls_colors('ln=1;36:or=:')
+ }},
+ {POST => sub {unlink 's' or die "s: $!\n";
+ restore_ls_colors; }},
+ ],
+
# Test for a bug that was introduced in coreutils-4.5.4; fixed in 4.5.5.
# To demonstrate it, the file in question (with executable bit set)
# must not be a command line argument.