summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--src/ls.c24
-rwxr-xr-xtests/ls/color-dtype-dir20
3 files changed, 37 insertions, 11 deletions
diff --git a/NEWS b/NEWS
index 0f4481697..270aa85b2 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,10 @@ GNU coreutils NEWS -*- outline -*-
to accommodate leap seconds.
[the bug dates back to the initial implementation]
+ ls --color now reverts to the color of a base file type consistently
+ when the color of a more specific type is disabled.
+ [bug introduced in coreutils-5.90]
+
** Changes in behavior
id no longer prints SELinux " context=..." when the POSIXLY_CORRECT
diff --git a/src/ls.c b/src/ls.c
index 6d81dab0e..10d024bac 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -4103,7 +4103,7 @@ print_color_indicator (const char *name, mode_t mode, int linkok,
bool stat_ok, enum filetype filetype,
nlink_t nlink)
{
- int type;
+ enum indicator_no type;
struct color_ext_type *ext; /* Color extension */
size_t len; /* Length of name */
@@ -4121,27 +4121,29 @@ print_color_indicator (const char *name, mode_t mode, int linkok,
if (S_ISREG (mode))
{
type = C_FILE;
- if ((mode & S_ISUID) != 0)
+
+ if ((mode & S_ISUID) != 0 && is_colored (C_SETUID))
type = C_SETUID;
- else if ((mode & S_ISGID) != 0)
+ else if ((mode & S_ISGID) != 0 && is_colored (C_SETGID))
type = C_SETGID;
- else if (is_colored (C_CAP) && has_capability (name))
+ else if (has_capability (name) && is_colored (C_CAP))
type = C_CAP;
- else if ((mode & S_IXUGO) != 0)
+ else if ((mode & S_IXUGO) != 0 && is_colored (C_EXEC))
type = C_EXEC;
- else if (is_colored (C_MULTIHARDLINK) && (1 < nlink))
+ else if ((1 < nlink) && is_colored (C_MULTIHARDLINK))
type = C_MULTIHARDLINK;
}
else if (S_ISDIR (mode))
{
- if ((mode & S_ISVTX) && (mode & S_IWOTH))
+ type = C_DIR;
+
+ if ((mode & S_ISVTX) && (mode & S_IWOTH)
+ && is_colored (C_STICKY_OTHER_WRITABLE))
type = C_STICKY_OTHER_WRITABLE;
- else if ((mode & S_IWOTH) != 0)
+ else if ((mode & S_IWOTH) != 0 && is_colored (C_OTHER_WRITABLE))
type = C_OTHER_WRITABLE;
- else if ((mode & S_ISVTX) != 0)
+ else if ((mode & S_ISVTX) != 0 && is_colored (C_STICKY))
type = C_STICKY;
- else
- type = C_DIR;
}
else if (S_ISLNK (mode))
type = ((!linkok && color_indicator[C_ORPHAN].string)
diff --git a/tests/ls/color-dtype-dir b/tests/ls/color-dtype-dir
index 5381a6684..3ccf10eb8 100755
--- a/tests/ls/color-dtype-dir
+++ b/tests/ls/color-dtype-dir
@@ -50,4 +50,24 @@ EOF
compare out exp || fail=1
+rm exp
+
+# Turn off colors for other-writable dirs and ensure
+# we fall back to the color for standard directories.
+
+LS_COLORS="ow=:" ls --color=always > out || fail=1
+cat -A out > o1 || fail=1
+echo >> o1 || fail=1
+mv o1 out || fail=1
+
+cat <<\EOF > exp || fail=1
+^[[0m^[[01;34md^[[0m$
+^[[01;34mother-writable^[[0m$
+out$
+^[[37;44msticky^[[0m$
+^[[m
+EOF
+
+compare out exp || fail=1
+
Exit $fail