aboutsummaryrefslogtreecommitdiffstats
path: root/src/ls.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ls.c')
-rw-r--r--src/ls.c99
1 files changed, 49 insertions, 50 deletions
diff --git a/src/ls.c b/src/ls.c
index 553090dc5..08fdf5fdc 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -93,6 +93,7 @@
#include "dev-ino.h"
#include "error.h"
#include "filenamecat.h"
+#include "hard-locale.h"
#include "hash.h"
#include "human.h"
#include "filemode.h"
@@ -323,7 +324,7 @@ static bool color_symlink_as_referent;
/* mode of appropriate file for colorization */
#define FILE_OR_LINK_MODE(File) \
- ((color_symlink_as_referent & (File)->linkok) \
+ ((color_symlink_as_referent && (File)->linkok) \
? (File)->linkmode : (File)->stat.st_mode)
@@ -1175,7 +1176,7 @@ stophandler (int sig)
static void
process_signals (void)
{
- while (interrupt_signal | stop_signal_count)
+ while (interrupt_signal || stop_signal_count)
{
int sig;
int stops;
@@ -2470,13 +2471,14 @@ print_dir (char const *name, char const *realname, bool command_line_arg)
error (0, 0, _("%s: not listing already-listed directory"),
quotearg_colon (name));
closedir (dirp);
+ set_exit_status (true);
return;
}
DEV_INO_PUSH (dir_stat.st_dev, dir_stat.st_ino);
}
- if (recursive | print_dir_name)
+ if (recursive || print_dir_name)
{
if (!first)
DIRED_PUTCHAR ('\n');
@@ -2800,17 +2802,6 @@ gobble_file (char const *name, enum filetype type, ino_t inode,
: lgetfilecon (absolute_name, &f->scontext));
err = (attr_len < 0);
- /* Contrary to its documented API, getfilecon may return 0,
- yet set f->scontext to NULL (on at least Debian's libselinux1
- 2.0.15-2+b1), so work around that bug.
- FIXME: remove this work-around in 2011, or whenever affected
- versions of libselinux are long gone. */
- if (attr_len == 0)
- {
- err = 0;
- f->scontext = xstrdup ("unlabeled");
- }
-
if (err == 0)
have_selinux = ! STREQ ("unlabeled", f->scontext);
else
@@ -2884,7 +2875,7 @@ gobble_file (char const *name, enum filetype type, ino_t inode,
f->filetype = symbolic_link;
else if (S_ISDIR (f->stat.st_mode))
{
- if (command_line_arg & !immediate_dirs)
+ if (command_line_arg && !immediate_dirs)
f->filetype = arg_directory;
else
f->filetype = directory;
@@ -3554,9 +3545,19 @@ format_group_width (gid_t g)
return format_user_or_group_width (numeric_ids ? NULL : getgroup (g), g);
}
+/* Return a pointer to a formatted version of F->stat.st_ino,
+ possibly using buffer, BUF, of length BUFLEN, which must be at least
+ INT_BUFSIZE_BOUND (uintmax_t) bytes. */
+static char *
+format_inode (char *buf, size_t buflen, const struct fileinfo *f)
+{
+ assert (INT_BUFSIZE_BOUND (uintmax_t) <= buflen);
+ return (f->stat_ok && f->stat.st_ino != NOT_AN_INODE_NUMBER
+ ? umaxtostr (f->stat.st_ino, buf)
+ : (char *) "?");
+}
/* Print information about F in long format. */
-
static void
print_long_format (const struct fileinfo *f)
{
@@ -3613,9 +3614,7 @@ print_long_format (const struct fileinfo *f)
{
char hbuf[INT_BUFSIZE_BOUND (uintmax_t)];
sprintf (p, "%*s ", inode_number_width,
- (f->stat.st_ino == NOT_AN_INODE_NUMBER
- ? "?"
- : umaxtostr (f->stat.st_ino, hbuf)));
+ format_inode (hbuf, sizeof hbuf, f));
/* Increment by strlen (p) here, rather than by inode_number_width + 1.
The latter is wrong when inode_number_width is zero. */
p += strlen (p);
@@ -3651,7 +3650,7 @@ print_long_format (const struct fileinfo *f)
DIRED_INDENT ();
- if (print_owner | print_group | print_author | print_scontext)
+ if (print_owner || print_group || print_author || print_scontext)
{
DIRED_FPUTS (buf, stdout, p - buf);
@@ -4002,12 +4001,13 @@ print_file_name_and_frills (const struct fileinfo *f, size_t start_col)
if (print_inode)
printf ("%*s ", format == with_commas ? 0 : inode_number_width,
- umaxtostr (f->stat.st_ino, buf));
+ format_inode (buf, sizeof buf, f));
if (print_block_size)
printf ("%*s ", format == with_commas ? 0 : block_size_width,
- human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts,
- ST_NBLOCKSIZE, output_block_size));
+ ! f->stat_ok ? "?"
+ : human_readable (ST_NBLOCKS (f->stat), buf, human_output_opts,
+ ST_NBLOCKSIZE, output_block_size));
if (print_scontext)
printf ("%*s ", format == with_commas ? 0 : scontext_width, f->scontext);
@@ -4102,7 +4102,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 */
@@ -4120,27 +4120,30 @@ 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;
+ /* has_capability() called second for performance. */
else if (is_colored (C_CAP) && has_capability (name))
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)
@@ -4221,9 +4224,10 @@ length_of_file_name_and_frills (const struct fileinfo *f)
if (print_block_size)
len += 1 + (format == with_commas
- ? strlen (human_readable (ST_NBLOCKS (f->stat), buf,
- human_output_opts, ST_NBLOCKSIZE,
- output_block_size))
+ ? strlen (! f->stat_ok ? "?"
+ : human_readable (ST_NBLOCKS (f->stat), buf,
+ human_output_opts, ST_NBLOCKSIZE,
+ output_block_size))
: block_size_width);
if (print_scontext)
@@ -4543,7 +4547,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
-b, --escape print octal escapes for nongraphic characters\n\
"), stdout);
fputs (_("\
- --block-size=SIZE use SIZE-byte blocks\n\
+ --block-size=SIZE use SIZE-byte blocks. See SIZE format below\n\
-B, --ignore-backups do not list implied entries ending with ~\n\
-c with -lt: sort by, and show, ctime (time of last\n\
modification of file status information)\n\
@@ -4552,8 +4556,8 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (_("\
-C list entries by columns\n\
- --color[=WHEN] control whether color is used to distinguish file\n\
- types. WHEN may be `never', `always', or `auto'\n\
+ --color[=WHEN] colorize the output. WHEN defaults to `always'\n\
+ or can be `never' or `auto'. More info below\n\
-d, --directory list directory entries instead of contents,\n\
and do not dereference symbolic links\n\
-D, --dired generate output designed for Emacs' dired mode\n\
@@ -4664,18 +4668,13 @@ Mandatory arguments to long options are mandatory for short options too.\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\n\
-SIZE may be (or may be an integer optionally followed by) one of following:\n\
-kB 1000, K 1024, MB 1000*1000, M 1024*1024, and so on for G, T, P, E, Z, Y.\n\
-"), stdout);
+ emit_size_note ();
fputs (_("\
\n\
-By default, color is not used to distinguish types of files. That is\n\
-equivalent to using --color=none. Using the --color option without the\n\
-optional WHEN argument is equivalent to using --color=always. With\n\
---color=auto, color codes are output only if standard output is connected\n\
-to a terminal (tty). The environment variable LS_COLORS can influence the\n\
-colors, and can be set easily by the dircolors command.\n\
+Using color to distinguish file types is disabled both by default and\n\
+with --color=never. With --color=auto, ls emits color codes only when\n\
+standard output is connected to a terminal. The LS_COLORS environment\n\
+variable can change the settings. Use the dircolors command to set it.\n\
"), stdout);
fputs (_("\
\n\
@@ -4684,7 +4683,7 @@ Exit status:\n\
1 if minor problems (e.g., cannot access subdirectory),\n\
2 if serious trouble (e.g., cannot access command-line argument).\n\
"), stdout);
- emit_bug_reporting_address ();
+ emit_ancillary_info ();
}
exit (status);
}