summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2011-12-08 10:49:03 +0100
committerJim Meyering <meyering@redhat.com>2011-12-08 12:17:54 +0100
commitc592a00f8f8c7e6baeff575a3762459173153635 (patch)
tree816826369d86abf2dda38529803bd12403cf29b9
parent6eb3cf234fef5522c0a206222e77f170c2ad6959 (diff)
downloadcoreutils-c592a00f8f8c7e6baeff575a3762459173153635.tar.xz
ls: be responsive to interrupts when color-listing large directories
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>
-rw-r--r--NEWS3
-rw-r--r--THANKS.in1
-rw-r--r--src/ls.c7
3 files changed, 10 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index de3888ddb..0d4c83b67 100644
--- 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
diff --git a/THANKS.in b/THANKS.in
index 5ecc29e63..afed5d451 100644
--- 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
diff --git a/src/ls.c b/src/ls.c
index 8be9b6aed..0d64bab15 100644
--- 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]);