Blame SOURCES/coreutils-8.22-ls-interruption.patch

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