Kamil Dudka 380647
From 9338b244572e07bbff314b3570228e8cf43f1300 Mon Sep 17 00:00:00 2001
Kamil Dudka 380647
From: Kamil Dudka <kdudka@redhat.com>
Kamil Dudka 380647
Date: Tue, 6 Sep 2016 17:38:26 +0200
Kamil Dudka 380647
Subject: [PATCH] ls: allow interruption when reading slow directories
Kamil Dudka 380647
Kamil Dudka 380647
Postpone installation of signal handlers until they're needed.
Kamil Dudka 380647
That is right before the first escape sequence is printed.
Kamil Dudka 380647
Kamil Dudka 380647
* src/ls.c (signal_setup): A new function refactored from main()
Kamil Dudka 380647
to set and restore signal handlers.
Kamil Dudka 380647
(main): Move signal handler setup to put_indicator()
Kamil Dudka 380647
so that the default signal handling is untouched as long as possible.
Kamil Dudka 380647
Adjusted condition for restoring signal handlers to reflect the change.
Kamil Dudka 380647
(put_indicator): Install signal handlers if called for the very first
Kamil Dudka 380647
time.  It uses the same code that was in main() prior to this commit.
Kamil Dudka 380647
* NEWS: Mention the improvement.
Kamil Dudka 380647
Kamil Dudka 380647
See https://bugzilla.redhat.com/1365933
Kamil Dudka 380647
Fixes http://bugs.gnu.org/24232
Kamil Dudka 380647
Kamil Dudka 380647
Upstream-commit: 5445f7811ff945ea13aa2a0fd797eb4c0a0e4db0
Kamil Dudka 380647
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
Kamil Dudka 380647
---
Kamil Dudka 380647
 src/ls.c | 161 ++++++++++++++++++++++++++++++++++++---------------------------
Kamil Dudka 380647
 1 file changed, 93 insertions(+), 68 deletions(-)
Kamil Dudka 380647
Kamil Dudka 380647
diff --git a/src/ls.c b/src/ls.c
Kamil Dudka 380647
index d976036..66df307 100644
Kamil Dudka 380647
--- a/src/ls.c
Kamil Dudka 380647
+++ b/src/ls.c
Kamil Dudka 380647
@@ -1244,13 +1244,12 @@ process_signals (void)
Kamil Dudka 380647
     }
Kamil Dudka 380647
 }
Kamil Dudka 380647
 
Kamil Dudka 380647
-int
Kamil Dudka 380647
-main (int argc, char **argv)
Kamil Dudka 380647
-{
Kamil Dudka 380647
-  int i;
Kamil Dudka 380647
-  struct pending *thispend;
Kamil Dudka 380647
-  int n_files;
Kamil Dudka 380647
+/* Setup signal handlers if INIT is true,
Kamil Dudka 380647
+   otherwise restore to the default.  */
Kamil Dudka 380647
 
Kamil Dudka 380647
+static void
Kamil Dudka 380647
+signal_setup (bool init)
Kamil Dudka 380647
+{
Kamil Dudka 380647
   /* The signals that are trapped, and the number of such signals.  */
Kamil Dudka 380647
   static int const sig[] =
Kamil Dudka 380647
     {
Kamil Dudka 380647
@@ -1278,8 +1277,77 @@ main (int argc, char **argv)
Kamil Dudka 380647
   enum { nsigs = ARRAY_CARDINALITY (sig) };
Kamil Dudka 380647
 
Kamil Dudka 380647
 #if ! SA_NOCLDSTOP
Kamil Dudka 380647
-  bool caught_sig[nsigs];
Kamil Dudka 380647
+  static bool caught_sig[nsigs];
Kamil Dudka 380647
+#endif
Kamil Dudka 380647
+
Kamil Dudka 380647
+  int j;
Kamil Dudka 380647
+
Kamil Dudka 380647
+  if (init)
Kamil Dudka 380647
+    {
Kamil Dudka 380647
+#if SA_NOCLDSTOP
Kamil Dudka 380647
+      struct sigaction act;
Kamil Dudka 380647
+
Kamil Dudka 380647
+      sigemptyset (&caught_signals);
Kamil Dudka 380647
+      for (j = 0; j < nsigs; j++)
Kamil Dudka 380647
+        {
Kamil Dudka 380647
+          sigaction (sig[j], NULL, &act;;
Kamil Dudka 380647
+          if (act.sa_handler != SIG_IGN)
Kamil Dudka 380647
+            sigaddset (&caught_signals, sig[j]);
Kamil Dudka 380647
+        }
Kamil Dudka 380647
+
Kamil Dudka 380647
+      act.sa_mask = caught_signals;
Kamil Dudka 380647
+      act.sa_flags = SA_RESTART;
Kamil Dudka 380647
+
Kamil Dudka 380647
+      for (j = 0; j < nsigs; j++)
Kamil Dudka 380647
+        if (sigismember (&caught_signals, sig[j]))
Kamil Dudka 380647
+          {
Kamil Dudka 380647
+            act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler;
Kamil Dudka 380647
+            sigaction (sig[j], &act, NULL);
Kamil Dudka 380647
+          }
Kamil Dudka 380647
+#else
Kamil Dudka 380647
+      for (j = 0; j < nsigs; j++)
Kamil Dudka 380647
+        {
Kamil Dudka 380647
+          caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN);
Kamil Dudka 380647
+          if (caught_sig[j])
Kamil Dudka 380647
+            {
Kamil Dudka 380647
+              signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler);
Kamil Dudka 380647
+              siginterrupt (sig[j], 0);
Kamil Dudka 380647
+            }
Kamil Dudka 380647
+        }
Kamil Dudka 380647
 #endif
Kamil Dudka 380647
+    }
Kamil Dudka 380647
+  else /* restore.  */
Kamil Dudka 380647
+    {
Kamil Dudka 380647
+#if SA_NOCLDSTOP
Kamil Dudka 380647
+      for (j = 0; j < nsigs; j++)
Kamil Dudka 380647
+        if (sigismember (&caught_signals, sig[j]))
Kamil Dudka 380647
+          signal (sig[j], SIG_DFL);
Kamil Dudka 380647
+#else
Kamil Dudka 380647
+      for (j = 0; j < nsigs; j++)
Kamil Dudka 380647
+        if (caught_sig[j])
Kamil Dudka 380647
+          signal (sig[j], SIG_DFL);
Kamil Dudka 380647
+#endif
Kamil Dudka 380647
+    }
Kamil Dudka 380647
+}
Kamil Dudka 380647
+
Kamil Dudka 380647
+static inline void
Kamil Dudka 380647
+signal_init (void)
Kamil Dudka 380647
+{
Kamil Dudka 380647
+  signal_setup (true);
Kamil Dudka 380647
+}
Kamil Dudka 380647
+
Kamil Dudka 380647
+static inline void
Kamil Dudka 380647
+signal_restore (void)
Kamil Dudka 380647
+{
Kamil Dudka 380647
+  signal_setup (false);
Kamil Dudka 380647
+}
Kamil Dudka 380647
+
Kamil Dudka 380647
+int
Kamil Dudka 380647
+main (int argc, char **argv)
Kamil Dudka 380647
+{
Kamil Dudka 380647
+  int i;
Kamil Dudka 380647
+  struct pending *thispend;
Kamil Dudka 380647
+  int n_files;
Kamil Dudka 380647
 
Kamil Dudka 380647
   initialize_main (&argc, &argv);
Kamil Dudka 380647
   set_program_name (argv[0]);
Kamil Dudka 380647
@@ -1314,46 +1382,6 @@ main (int argc, char **argv)
Kamil Dudka 380647
           || (is_colored (C_EXEC) && color_symlink_as_referent)
Kamil Dudka 380647
           || (is_colored (C_MISSING) && format == long_format))
Kamil Dudka 380647
         check_symlink_color = true;
Kamil Dudka 380647
-
Kamil Dudka 380647
-      /* If the standard output is a controlling terminal, watch out
Kamil Dudka 380647
-         for signals, so that the colors can be restored to the
Kamil Dudka 380647
-         default state if "ls" is suspended or interrupted.  */
Kamil Dudka 380647
-
Kamil Dudka 380647
-      if (0 <= tcgetpgrp (STDOUT_FILENO))
Kamil Dudka 380647
-        {
Kamil Dudka 380647
-          int j;
Kamil Dudka 380647
-#if SA_NOCLDSTOP
Kamil Dudka 380647
-          struct sigaction act;
Kamil Dudka 380647
-
Kamil Dudka 380647
-          sigemptyset (&caught_signals);
Kamil Dudka 380647
-          for (j = 0; j < nsigs; j++)
Kamil Dudka 380647
-            {
Kamil Dudka 380647
-              sigaction (sig[j], NULL, &act;;
Kamil Dudka 380647
-              if (act.sa_handler != SIG_IGN)
Kamil Dudka 380647
-                sigaddset (&caught_signals, sig[j]);
Kamil Dudka 380647
-            }
Kamil Dudka 380647
-
Kamil Dudka 380647
-          act.sa_mask = caught_signals;
Kamil Dudka 380647
-          act.sa_flags = SA_RESTART;
Kamil Dudka 380647
-
Kamil Dudka 380647
-          for (j = 0; j < nsigs; j++)
Kamil Dudka 380647
-            if (sigismember (&caught_signals, sig[j]))
Kamil Dudka 380647
-              {
Kamil Dudka 380647
-                act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler;
Kamil Dudka 380647
-                sigaction (sig[j], &act, NULL);
Kamil Dudka 380647
-              }
Kamil Dudka 380647
-#else
Kamil Dudka 380647
-          for (j = 0; j < nsigs; j++)
Kamil Dudka 380647
-            {
Kamil Dudka 380647
-              caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN);
Kamil Dudka 380647
-              if (caught_sig[j])
Kamil Dudka 380647
-                {
Kamil Dudka 380647
-                  signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler);
Kamil Dudka 380647
-                  siginterrupt (sig[j], 0);
Kamil Dudka 380647
-                }
Kamil Dudka 380647
-            }
Kamil Dudka 380647
-#endif
Kamil Dudka 380647
-        }
Kamil Dudka 380647
     }
Kamil Dudka 380647
 
Kamil Dudka 380647
   if (dereference == DEREF_UNDEFINED)
Kamil Dudka 380647
@@ -1466,32 +1494,21 @@ main (int argc, char **argv)
Kamil Dudka 380647
       print_dir_name = true;
Kamil Dudka 380647
     }
Kamil Dudka 380647
 
Kamil Dudka 380647
-  if (print_with_color)
Kamil Dudka 380647
+  if (print_with_color && used_color)
Kamil Dudka 380647
     {
Kamil Dudka 380647
       int j;
Kamil Dudka 380647
 
Kamil Dudka 380647
-      if (used_color)
Kamil Dudka 380647
-        {
Kamil Dudka 380647
-          /* Skip the restore when it would be a no-op, i.e.,
Kamil Dudka 380647
-             when left is "\033[" and right is "m".  */
Kamil Dudka 380647
-          if (!(color_indicator[C_LEFT].len == 2
Kamil Dudka 380647
-                && memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0
Kamil Dudka 380647
-                && color_indicator[C_RIGHT].len == 1
Kamil Dudka 380647
-                && color_indicator[C_RIGHT].string[0] == 'm'))
Kamil Dudka 380647
-            restore_default_color ();
Kamil Dudka 380647
-        }
Kamil Dudka 380647
+      /* Skip the restore when it would be a no-op, i.e.,
Kamil Dudka 380647
+         when left is "\033[" and right is "m".  */
Kamil Dudka 380647
+      if (!(color_indicator[C_LEFT].len == 2
Kamil Dudka 380647
+            && memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0
Kamil Dudka 380647
+            && color_indicator[C_RIGHT].len == 1
Kamil Dudka 380647
+            && color_indicator[C_RIGHT].string[0] == 'm'))
Kamil Dudka 380647
+        restore_default_color ();
Kamil Dudka 380647
+
Kamil Dudka 380647
       fflush (stdout);
Kamil Dudka 380647
 
Kamil Dudka 380647
-      /* Restore the default signal handling.  */
Kamil Dudka 380647
-#if SA_NOCLDSTOP
Kamil Dudka 380647
-      for (j = 0; j < nsigs; j++)
Kamil Dudka 380647
-        if (sigismember (&caught_signals, sig[j]))
Kamil Dudka 380647
-          signal (sig[j], SIG_DFL);
Kamil Dudka 380647
-#else
Kamil Dudka 380647
-      for (j = 0; j < nsigs; j++)
Kamil Dudka 380647
-        if (caught_sig[j])
Kamil Dudka 380647
-          signal (sig[j], SIG_DFL);
Kamil Dudka 380647
-#endif
Kamil Dudka 380647
+      signal_restore ();
Kamil Dudka 380647
 
Kamil Dudka 380647
       /* Act on any signals that arrived before the default was restored.
Kamil Dudka 380647
          This can process signals out of order, but there doesn't seem to
Kamil Dudka 380647
@@ -4482,6 +4499,14 @@ put_indicator (const struct bin_str *ind)
Kamil Dudka 380647
   if (! used_color)
Kamil Dudka 380647
     {
Kamil Dudka 380647
       used_color = true;
Kamil Dudka 380647
+
Kamil Dudka 380647
+      /* If the standard output is a controlling terminal, watch out
Kamil Dudka 380647
+         for signals, so that the colors can be restored to the
Kamil Dudka 380647
+         default state if "ls" is suspended or interrupted.  */
Kamil Dudka 380647
+
Kamil Dudka 380647
+      if (0 <= tcgetpgrp (STDOUT_FILENO))
Kamil Dudka 380647
+        signal_init ();
Kamil Dudka 380647
+
Kamil Dudka 380647
       prep_non_filename_text ();
Kamil Dudka 380647
     }
Kamil Dudka 380647
 
Kamil Dudka 380647
-- 
Kamil Dudka 380647
2.7.4
Kamil Dudka 380647