|
|
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 |
|