ls: be responsive to interrupts when color-listing large directories
authorJim Meyering <meyering@redhat.com>
Thu, 8 Dec 2011 09:49:03 +0000 (10:49 +0100)
committerJim Meyering <meyering@redhat.com>
Thu, 8 Dec 2011 11:17:54 +0000 (12:17 +0100)
Starting with commit adc30a83, when using --color, ls inhibited
interrupts to avoid corrupting the state of an output terminal.
However, for very large directories, that inhibition rendered ls
uninterruptible for too long, including a potentially long period
even before any output is generated.
* src/ls.c: Two phases of processing are time-consuming enough that
they can provoke this: the readdir loop and the printing loop.  The
printing was supposed to be covered by a call to process_signals in
(print_name_with_quoting): ... but that call was mistakenly guarded
by a condition that might be false for many or even all files being
processed.  Call process_signals unconditionally.
(print_dir): Also call process_signals in the readdir loop.
* NEWS (Bug fixes): Mention it.
Reported by Arkadiusz Miśkiewicz in http://bugs.gnu.org/10243
Co-authored-by: Eric Blake <eblake@redhat.com>
NEWS
THANKS.in
src/ls.c

diff --git a/NEWS b/NEWS
index de3888d..0d4c83b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,9 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 ** Bug fixes
 
+  ls --color many-entry-directory was uninterruptible for too long
+  [bug introduced in coreutils-5.2.1]
+
   ls's -k option no longer affects how ls -l outputs file sizes.
   It now affects only the per-directory block counts written by -l,
   and the sizes written by -s.  This is for compatibility with BSD
index 5ecc29e..afed5d4 100644 (file)
--- a/THANKS.in
+++ b/THANKS.in
@@ -59,6 +59,7 @@ Anthony Thyssen                     anthony@griffith.edu.au
 Antonio Rendas                      ajrendas@yahoo.com
 Ariel Faigon                        ariel@cthulhu.engr.sgi.com
 Arjan Opmeer                        arjan.opmeer@gmail.com
+Arkadiusz Miśkiewicz                arekm@maven.pl
 Arne Henrik Juul                    arnej@imf.unit.no
 Arnold Robbins                      arnold@skeeve.com
 Arthur Pool                         pool@commerce.uq.edu.au
index 8be9b6a..0d64bab 100644 (file)
--- a/src/ls.c
+++ b/src/ls.c
@@ -2595,6 +2595,11 @@ print_dir (char const *name, char const *realname, bool command_line_arg)
         }
       else
         break;
+
+      /* When processing a very large directory, and since we've inhibited
+         interrupts, this loop would take so long that ls would be annoyingly
+         uninterruptible.  This ensures that it handles signals promptly.  */
+      process_signals ();
     }
 
   if (closedir (dirp) != 0)
@@ -4060,9 +4065,9 @@ print_name_with_quoting (const struct fileinfo *f,
   if (stack)
     PUSH_CURRENT_DIRED_POS (stack);
 
+  process_signals ();
   if (used_color_this_time)
     {
-      process_signals ();
       prep_non_filename_text ();
       if (start_col / line_length != (start_col + width - 1) / line_length)
         put_indicator (&color_indicator[C_CLR_TO_EOL]);