[Libguestfs] [PATCH] fish: reset the console on ^Z RHBZ#1213844
Pino Toscano
ptoscano at redhat.com
Wed Feb 17 14:17:54 UTC 2016
Hi,
On Tuesday 16 February 2016 18:06:44 Maros Zatko wrote:
> Patch registers SIGTSTP hook where it sends reset terminal color
> control sequence.
> ---
IMHO the commit message and the patch (in form of comments) could get
more explanation of what is being done, and why each step is done.
Signal handling is a tricky part of C programming, so everything needs
to be properly documented in order to not break it in the future.
> 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);
> +}
sigaction() is used to install the signal handler for SIGTSTP, but
signal() is used in these functions (called from the signal handler):
this is a bad, you should not mix sigaction() and signal() usages;
see the sigaction() documentation [1].
> +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);
Neither printf() nor fflush() are async-signal-safe functions, and
thus you cannot use them in a signal handler; see [2] for the list of
supported functions. You can use write() and fsync() though.
> + /* Unblock SIGTSTP. */
> + sigemptyset (&set);
> + sigaddset (&set, SIGTSTP);
> + sigprocmask (SIG_UNBLOCK, &set, NULL);
Sounds like this is what the SA_NODEFER flag for sigaction() does.
> +
> + restore_stophandler ();
> +
> + /* Stop ourselves. */
> + kill (0, SIGTSTP);
> +
> + /* Now we're stopped ... */
> +
> + /* Reset the curses SIGTSTP signal handler. */
> + set_stophandler ();
IMHO a better way would be to save the previous SIGTSTP signal handler
(which sigaction() gives you), and call it manually
> +
> +#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.
>
[1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html
[2] http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04
Thanks,
--
Pino Toscano
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part.
URL: <http://listman.redhat.com/archives/libguestfs/attachments/20160217/c9888565/attachment.sig>
More information about the Libguestfs
mailing list