summaryrefslogtreecommitdiff
path: root/src
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 /src
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>
Diffstat (limited to 'src')
-rw-r--r--src/ls.c7
1 files changed, 6 insertions, 1 deletions
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]);