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