diff options
author | Jim Meyering <jim@meyering.net> | 2002-11-09 22:27:27 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2002-11-09 22:27:27 +0000 |
commit | 85490682b7297846a8258ebc05e409330bb3255d (patch) | |
tree | 3c6addada5a6d2fae8bd78c7a5d198b73dc940bd /src | |
parent | cd0013e0eac4a9a15323ace11deb5cdce185c768 (diff) | |
download | coreutils-85490682b7297846a8258ebc05e409330bb3255d.tar.xz |
ls --color: restore terminal state (color) upon signal.
Include "full-write.h" and <signal.h>.
(restore_default_color, restore_default_color_handler): New functions.
(sigtstp_handler, put_indicator_direct): New functions.
(main) [print_with_color]: Register signal handlers.
Patch mostly by Solar Designer and Stanislav Ievlev.
Diffstat (limited to 'src')
-rw-r--r-- | src/ls.c | 44 |
1 files changed, 44 insertions, 0 deletions
@@ -62,6 +62,7 @@ #include <grp.h> #include <pwd.h> #include <getopt.h> +#include <signal.h> /* Get MB_CUR_MAX. */ #if HAVE_STDLIB_H @@ -104,6 +105,7 @@ int wcwidth (); #include "dirname.h" #include "dirfd.h" #include "error.h" +#include "full-write.h" #include "hard-locale.h" #include "hash.h" #include "human.h" @@ -268,6 +270,7 @@ static uintmax_t gobble_file PARAMS ((const char *name, enum filetype type, static void print_color_indicator PARAMS ((const char *name, mode_t mode, int linkok)); static void put_indicator PARAMS ((const struct bin_str *ind)); +static int put_indicator_direct PARAMS ((const struct bin_str *ind)); static int length_of_file_name_and_frills PARAMS ((const struct fileinfo *f)); static void add_ignore_pattern PARAMS ((const char *pattern)); static void attach PARAMS ((char *dest, const char *dirname, const char *name)); @@ -994,6 +997,28 @@ free_pending_ent (struct pending *p) free (p); } +static void +restore_default_color (void) +{ + if (put_indicator_direct (&color_indicator[C_LEFT]) == 0) + put_indicator_direct (&color_indicator[C_RIGHT]); +} + +static void +restore_default_color_handler (int signum) +{ + restore_default_color (); + _exit (128 + signum); +} + +static void +sigtstp_handler (int signum) +{ + signal (SIGTSTP, sigtstp_handler); + restore_default_color (); + raise (SIGSTOP); +} + int main (int argc, char **argv) { @@ -1031,6 +1056,11 @@ main (int argc, char **argv) || (color_indicator[C_MISSING].string != NULL && format == long_format)) check_symlink_color = 1; + + signal (SIGINT, restore_default_color_handler); + signal (SIGTERM, restore_default_color_handler); + signal (SIGQUIT, restore_default_color_handler); + signal (SIGTSTP, sigtstp_handler); } if (dereference == DEREF_UNDEFINED) @@ -3307,6 +3337,20 @@ put_indicator (const struct bin_str *ind) putchar (*(p++)); } +/* Output a color indicator, but don't use stdio, for use from signal handlers. + Return zero if the write is successful or if the string length is zero. + Return nonzero if the write fails. */ +static int +put_indicator_direct (const struct bin_str *ind) +{ + size_t len; + if (ind->len <= 0) + return 0; + + len = ind->len; + return (full_write (STDOUT_FILENO, ind->string, len) != len); +} + static int length_of_file_name_and_frills (const struct fileinfo *f) { |