From e804b4ca6c9e89b668547797adbe1ea7b74e5dbf Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 27 Oct 2008 15:38:23 +0100 Subject: [PATCH] ls: --color now highlights hard linked files, too * 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 | 2 ++ src/dircolors.c | 5 +++-- src/dircolors.hin | 1 + src/ls.c | 29 ++++++++++++++++++----------- tests/Makefile.am | 1 + tests/ls/hardlink | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 71 insertions(+), 13 deletions(-) create mode 100755 tests/ls/hardlink diff --git a/NEWS b/NEWS index 79d5148..cbea67c 100644 --- 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 diff --git a/src/dircolors.c b/src/dircolors.c index 79109b9..0980e3d 100644 --- a/src/dircolors.c +++ b/src/dircolors.c @@ -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)); diff --git a/src/dircolors.hin b/src/dircolors.hin index 5137cc6..e0b4a6d 100644 --- a/src/dircolors.hin +++ b/src/dircolors.hin @@ -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 links FIFO 40;33 # pipe SOCK 01;35 # socket DOOR 01;35 # door diff --git a/src/ls.c b/src/ls.c index 590af7f..d5bd8d1 100644 --- 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)) { diff --git a/tests/Makefile.am b/tests/Makefile.am index 808c61e..0dabb56 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 index 0000000..80405c1 --- /dev/null +++ b/tests/ls/hardlink @@ -0,0 +1,46 @@ +#!/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 . + +if test "$VERBOSE" = yes; then + set -x + ls --version +fi + +. $srcdir/test-lib.sh + +# Don't let a different umask perturb the results. +umask 22 + +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 -- 1.5.4.1