Subject: Re: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color

From: Giuseppe Scrivano <[email-masked]>
Date: Tue, 10 Mar 2015 23:19:26 +0100

Paul Eggert <[email-masked]> writes:

> What happens if I type Control-C while colored output is streaming by
> my terminal?  Can it leave the terminal in a funny colored state?

No, the Control-C would leave the terminal in a funny state.  Thanks to
have pointed it out, I completely missed the ls.c code that handles
that.

What about amending the previous version with the patch below?

Regards,
Giuseppe

diff --git a/src/util.c b/src/util.c
index 3687b5e..5b28a07 100644
--- a/src/util.c
+++ b/src/util.c
@@ -24,6 +24,7 @@
 #include <system-quote.h>
 #include <xalloc.h>
 #include "xvasprintf.h"
+#include <signal.h>
 
 char const pr_program[] = PR_PROGRAM;
 
@@ -731,24 +732,56 @@ output_1_line (char const *base, char const *limit, char const *flag_format,
     }
 }
 
+static sigset_t old_sigproc_set;
 void
 set_color_context (enum colors con)
 {
+  int j;
+  sigset_t set;
+  static int const sig[] =
+    {
+      SIGTSTP,
+      SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM,
+#ifdef SIGPOLL
+      SIGPOLL,
+#endif
+#ifdef SIGPROF
+      SIGPROF,
+#endif
+#ifdef SIGVTALRM
+      SIGVTALRM,
+#endif
+#ifdef SIGXCPU
+      SIGXCPU,
+#endif
+#ifdef SIGXFSZ
+      SIGXFSZ,
+#endif
+    };
+
   if (! colors_enabled)
     return;
 
+  sigemptyset (&set);
+  for (j = 0; j < (sizeof (sig) / sizeof (*sig)); j++)
+    sigaddset (&set, sig[j]);
+
   switch (con)
     {
     case DELETE:
+      sigprocmask (SIG_BLOCK, &set, &old_sigproc_set);
       fprintf (outfile, "\x1B[31m");
       break;
 
     case ADD:
+      sigprocmask (SIG_BLOCK, &set, &old_sigproc_set);
       fprintf (outfile, "\x1B[32m");
       break;
 
     case RESET:
-      fprintf(outfile, "\x1b[0m");
+      fprintf (outfile, "\x1b[0m");
+      fflush (outfile);
+      sigprocmask (SIG_SETMASK, &old_sigproc_set, NULL);
       break;
     }
 }