]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
ls: --color now highlights hard linked files, too
authorKamil Dudka <kdudka@redhat.com>
Mon, 27 Oct 2008 14:38:23 +0000 (15:38 +0100)
committerJim Meyering <meyering@redhat.com>
Tue, 28 Oct 2008 20:08:30 +0000 (21:08 +0100)
* src/ls.c (print_color_indicator): Colorize hard linked files.
* src/dircolors.c: Add color for hard link.
* src/dircolors.hin: Add color for hard link.
* tests/ls/hardlink: Test for ls - colorize hard linked files.
* tests/Makefile.am (TESTS): Add ls/hardlink.
* NEWS: Mention the change.

NEWS
src/dircolors.c
src/dircolors.hin
src/ls.c
tests/Makefile.am
tests/ls/hardlink [new file with mode: 0755]

diff --git a/NEWS b/NEWS
index 79d51487686c64a93e7530d43025d63480b252a2..cbea67c3d97ae8ed539c400cfeaa92ba81a9e420 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,8 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 ** New features
 
+  ls --color now highlights hard linked files, too
+
   stat -f recognizes the Lustre file system type
 
 ** Bug fixes
index 79109b93455762f988c79eca44ea31ada455dd8a..0980e3df1a93c9f22bf16535facc512fd009ce13 100644 (file)
@@ -63,14 +63,15 @@ static const char *const slack_codes[] =
   "SYMLINK", "ORPHAN", "MISSING", "FIFO", "PIPE", "SOCK", "BLK", "BLOCK",
   "CHR", "CHAR", "DOOR", "EXEC", "LEFT", "LEFTCODE", "RIGHT", "RIGHTCODE",
   "END", "ENDCODE", "SUID", "SETUID", "SGID", "SETGID", "STICKY",
-  "OTHER_WRITABLE", "OWR", "STICKY_OTHER_WRITABLE", "OWT", "CAPABILITY", NULL
+  "OTHER_WRITABLE", "OWR", "STICKY_OTHER_WRITABLE", "OWT", "CAPABILITY",
+  "HARDLINK", NULL
 };
 
 static const char *const ls_codes[] =
 {
   "no", "no", "fi", "rs", "di", "ln", "ln", "ln", "or", "mi", "pi", "pi",
   "so", "bd", "bd", "cd", "cd", "do", "ex", "lc", "lc", "rc", "rc", "ec", "ec",
-  "su", "su", "sg", "sg", "st", "ow", "ow", "tw", "tw", "ca", NULL
+  "su", "su", "sg", "sg", "st", "ow", "ow", "tw", "tw", "ca", "hl", NULL
 };
 #define array_len(Array) (sizeof (Array) / sizeof *(Array))
 verify (array_len (slack_codes) == array_len (ls_codes));
index 5137cc6f1dac322a2c0dc9285a59eb79e21e2b16..63af8cb1f78126a379a3840647457e237c84c5d5 100644 (file)
@@ -69,6 +69,7 @@ RESET 0               # reset to "normal" color
 DIR 01;34      # directory
 LINK 01;36     # symbolic link.  (If you set this to 'target' instead of a
                # numerical value, the color is as for the file pointed to.)
+HARDLINK 44;37 # regular file with more than one link
 FIFO 40;33     # pipe
 SOCK 01;35     # socket
 DOOR 01;35     # door
index 590af7f05b3125eb008fcd312623961f0e9f56bc..d5bd8d1e0c26e01b48745cdffe56337fc7d216c6 100644 (file)
--- a/src/ls.c
+++ b/src/ls.c
@@ -217,7 +217,8 @@ static uintmax_t gobble_file (char const *name, enum filetype type,
                              ino_t inode, bool command_line_arg,
                              char const *dirname);
 static bool print_color_indicator (const char *name, mode_t mode, int linkok,
-                                  bool stat_ok, enum filetype type);
+                                  bool stat_ok, enum filetype type,
+                                  nlink_t nlink);
 static void put_indicator (const struct bin_str *ind);
 static void add_ignore_pattern (const char *pattern);
 static void attach (char *dest, const char *dirname, const char *name);
@@ -240,7 +241,7 @@ static void print_many_per_line (void);
 static void print_name_with_quoting (const char *p, mode_t mode,
                                     int linkok, bool stat_ok,
                                     enum filetype type,
-                                    struct obstack *stack);
+                                    struct obstack *stack, nlink_t nlink);
 static void prep_non_filename_text (void);
 static void print_type_indicator (bool stat_ok, mode_t mode,
                                  enum filetype type);
@@ -521,14 +522,14 @@ enum indicator_no
     C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK,
     C_FIFO, C_SOCK,
     C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID,
-    C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP
+    C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP, C_HARDLINK
   };
 
 static const char *const indicator_name[]=
   {
     "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so",
     "bd", "cd", "mi", "or", "ex", "do", "su", "sg", "st",
-    "ow", "tw", "ca", NULL
+    "ow", "tw", "ca", "hl", NULL
   };
 
 struct color_ext_type
@@ -561,7 +562,8 @@ static struct bin_str color_indicator[] =
     { LEN_STR_PAIR ("37;44") },                /* st: sticky: black on blue */
     { LEN_STR_PAIR ("34;42") },                /* ow: other-writable: blue on green */
     { LEN_STR_PAIR ("30;42") },                /* tw: ow w/ sticky: black on green */
-    { LEN_STR_PAIR ("30;41") },                /* capability: black on red */
+    { LEN_STR_PAIR ("30;41") },                /* ca: black on red */
+    { LEN_STR_PAIR ("44;37") },                /* hl: white on blue */
   };
 
 /* FIXME: comment  */
@@ -3636,7 +3638,8 @@ print_long_format (const struct fileinfo *f)
 
   DIRED_FPUTS (buf, stdout, p - buf);
   print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok,
-                          f->stat_ok, f->filetype, &dired_obstack);
+                          f->stat_ok, f->filetype, &dired_obstack,
+                          f->stat.st_nlink);
 
   if (f->filetype == symbolic_link)
     {
@@ -3644,7 +3647,8 @@ print_long_format (const struct fileinfo *f)
        {
          DIRED_FPUTS_LITERAL (" -> ", stdout);
          print_name_with_quoting (f->linkname, f->linkmode, f->linkok - 1,
-                                  f->stat_ok, f->filetype, NULL);
+                                  f->stat_ok, f->filetype, NULL,
+                                  f->stat.st_nlink);
          if (indicator_style != none)
            print_type_indicator (true, f->linkmode, unknown);
        }
@@ -3826,11 +3830,11 @@ quote_name (FILE *out, const char *name, struct quoting_options const *options,
 static void
 print_name_with_quoting (const char *p, mode_t mode, int linkok,
                         bool stat_ok, enum filetype type,
-                        struct obstack *stack)
+                        struct obstack *stack, nlink_t nlink)
 {
   bool used_color_this_time
     = (print_with_color
-       && print_color_indicator (p, mode, linkok, stat_ok, type));
+       && print_color_indicator (p, mode, linkok, stat_ok, type, nlink));
 
   if (stack)
     PUSH_CURRENT_DIRED_POS (stack);
@@ -3882,7 +3886,7 @@ print_file_name_and_frills (const struct fileinfo *f)
     printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext);
 
   print_name_with_quoting (f->name, FILE_OR_LINK_MODE (f), f->linkok,
-                          f->stat_ok, f->filetype, NULL);
+                          f->stat_ok, f->filetype, NULL, f->stat.st_nlink);
 
   if (indicator_style != none)
     print_type_indicator (f->stat_ok, f->stat.st_mode, f->filetype);
@@ -3964,7 +3968,8 @@ has_capability (char const *name ATTRIBUTE_UNUSED)
 /* Returns whether any color sequence was printed. */
 static bool
 print_color_indicator (const char *name, mode_t mode, int linkok,
-                      bool stat_ok, enum filetype filetype)
+                      bool stat_ok, enum filetype filetype,
+                      nlink_t nlink)
 {
   int type;
   struct color_ext_type *ext;  /* Color extension */
@@ -3992,6 +3997,8 @@ print_color_indicator (const char *name, mode_t mode, int linkok,
            type = C_CAP;
          else if ((mode & S_IXUGO) != 0)
            type = C_EXEC;
+         else if (1 < nlink)
+           type = C_HARDLINK;
        }
       else if (S_ISDIR (mode))
        {
index 808c61e41ac332ffe47ff4195b8b6f479d77ff42..0dabb563e7216ba47d36afc5d961036f9984de94 100644 (file)
@@ -324,6 +324,7 @@ TESTS =                                             \
   ls/dired                                     \
   ls/file-type                                 \
   ls/follow-slink                              \
+  ls/hardlink                                  \
   ls/infloop                                   \
   ls/inode                                     \
   ls/m-option                                  \
diff --git a/tests/ls/hardlink b/tests/ls/hardlink
new file mode 100755 (executable)
index 0000000..d65bb7a
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/sh
+# Ensure "ls --color" properly colorizes hard linked files.
+
+# Copyright (C) 2008 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if test "$VERBOSE" = yes; then
+  set -x
+  ls --version
+fi
+
+. $srcdir/test-lib.sh
+working_umask_or_skip_
+
+touch file file1 || framework_failure
+ln file1 file2 || skip_test_ "can't create hard link"
+code='44;37'
+fail=0
+
+# regular file - not hard linked
+LS_COLORS="hl=$code" ls -U1 --color=always file > out || fail=1
+printf "file\n" > out_ok || fail=1
+compare out out_ok || fail=1
+
+# hard links
+LS_COLORS="hl=$code" ls -U1 --color=always file1 file2 > out || fail=1
+printf "\033[0m\033[44;37mfile1\033[0m
+\033[44;37mfile2\033[0m
+\033[m" > out_ok || fail=1
+compare out out_ok || fail=1
+
+Exit $fail