Patch registers SIGTSTP hook where it sends reset terminal color
control sequence.
---
fish/fish.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/fish/fish.c b/fish/fish.c
index d26f8b3..b579898 100644
--- a/fish/fish.c
+++ b/fish/fish.c
@@ -73,6 +73,11 @@ static void cleanup_readline (void);
static char *decode_ps1 (const char *);
static void add_history_line (const char *);
#endif
+static void set_stophandler (void);
+static void restore_stophandler (void);
+static void user_control_z (int sig);
+
+static void (*otstpfn) = SIG_DFL;
static int override_progress_bars = -1;
static struct progress_bar *bar = NULL;
@@ -159,6 +164,64 @@ usage (int status)
exit (status);
}
+/*
+ * Set the TSTP handler.
+ */
+static void
+set_stophandler (void)
+{
+ otstpfn = signal (SIGTSTP, user_control_z);
+}
+
+/*
+ * Restore the TSTP handler.
+ */
+static void
+restore_stophandler (void)
+{
+ signal (SIGTSTP, otstpfn);
+}
+
+static void
+user_control_z (int sig)
+{
+ sigset_t oset, set;
+
+#ifdef HAVE_LIBREADLINE
+ /* Cleanup readline, unhook from terminal */
+ rl_free_line_state ();
+ rl_cleanup_after_signal ();
+#endif
+
+ /* Reset terminal color */
+#define RESETCOLOR "\033[0m"
+ printf (RESETCOLOR);
+ fflush (stdout);
+
+ /* Unblock SIGTSTP. */
+ sigemptyset (&set);
+ sigaddset (&set, SIGTSTP);
+ sigprocmask (SIG_UNBLOCK, &set, NULL);
+
+ restore_stophandler ();
+
+ /* Stop ourselves. */
+ kill (0, SIGTSTP);
+
+ /* Now we're stopped ... */
+
+ /* Reset the curses SIGTSTP signal handler. */
+ set_stophandler ();
+
+#ifdef HAVE_LIBREADLINE
+ /* Restore readline state */
+ rl_reset_after_signal ();
+#endif
+
+ /* Reset the signals. */
+ sigprocmask (SIG_SETMASK, &oset, NULL);
+}
+
int
main (int argc, char *argv[])
{
@@ -439,6 +502,15 @@ main (int argc, char *argv[])
exit (EXIT_FAILURE);
}
+ /* Register ^Z handler. We need it to reset terminal colors
+ */
+ if (is_interactive) {
+ memset (&sa, 0, sizeof sa);
+ sa.sa_handler = user_control_z;
+ sa.sa_flags = SA_RESTART;
+ sigaction (SIGTSTP, &sa, NULL);
+ }
+
/* Old-style -i syntax? Since -a/-d/-N and -i was disallowed
* previously, if we have -i without any drives but with something
* on the command line, it must be old-style syntax.
--
2.5.0