diff options
author | ru <ru@FreeBSD.org> | 2003-05-02 00:50:59 +0000 |
---|---|---|
committer | ru <ru@FreeBSD.org> | 2003-05-02 00:50:59 +0000 |
commit | b40fbbd2c63cff4ae8b5423e68ddd1ad45c20c79 (patch) | |
tree | 8b19493038ac4e0f080fe9ac26b4781fb7ccdf8d /contrib/texinfo/info | |
parent | a25bb496d250dbb5f860b0d7cf19e227f83bb71b (diff) | |
download | FreeBSD-src-b40fbbd2c63cff4ae8b5423e68ddd1ad45c20c79.zip FreeBSD-src-b40fbbd2c63cff4ae8b5423e68ddd1ad45c20c79.tar.gz |
Merge texinfo 4.5 changes onto the trunk.
Diffstat (limited to 'contrib/texinfo/info')
-rw-r--r-- | contrib/texinfo/info/signals.c | 173 |
1 files changed, 124 insertions, 49 deletions
diff --git a/contrib/texinfo/info/signals.c b/contrib/texinfo/info/signals.c index 954a739..76c3b2e 100644 --- a/contrib/texinfo/info/signals.c +++ b/contrib/texinfo/info/signals.c @@ -1,8 +1,9 @@ /* signals.c -- install and maintain Info signal handlers. - $Id: signals.c,v 1.6 1998/12/06 22:00:04 karl Exp $ + $Id: signals.c,v 1.4 2003/01/29 19:23:22 karl Exp $ $FreeBSD$ - Copyright (C) 1993, 94, 95, 98 Free Software Foundation, Inc. + Copyright (C) 1993, 1994, 1995, 1998, 2002, 2003 Free Software + Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,9 +30,6 @@ /* */ /* **************************************************************** */ -/* Non-zero when our signal handler has been called to handle SIGWINCH. */ -static int in_sigwinch = 0; - #if !defined (HAVE_SIGPROCMASK) && defined (HAVE_SIGSETMASK) /* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */ static void @@ -64,35 +62,89 @@ sigprocmask (operation, newset, oldset) /* */ /* **************************************************************** */ -typedef RETSIGTYPE signal_handler (); +#if defined (HAVE_SIGACTION) || defined (HAVE_SIGPROCMASK) ||\ + defined (HAVE_SIGSETMASK) +static void +mask_termsig (set) + sigset_t *set; +{ +# if defined (SIGTSTP) + sigaddset (set, SIGTSTP); + sigaddset (set, SIGTTOU); + sigaddset (set, SIGTTIN); +# endif +# if defined (SIGWINCH) + sigaddset (set, SIGWINCH); +# endif +#if defined (SIGINT) + sigaddset (set, SIGINT); +#endif +# if defined (SIGUSR1) + sigaddset (set, SIGUSR1); +# endif +} +#endif /* HAVE_SIGACTION || HAVE_SIGPROCMASK || HAVE_SIGSETMASK */ + +static RETSIGTYPE info_signal_proc (); +#if defined (HAVE_SIGACTION) +typedef struct sigaction signal_info; +signal_info info_signal_handler; -static RETSIGTYPE info_signal_handler (); -static signal_handler *old_TSTP, *old_TTOU, *old_TTIN; -static signal_handler *old_WINCH, *old_INT, *old_USR1, *old_CONT; +static void +set_termsig (sig, old) + int sig; + signal_info *old; +{ + sigaction (sig, &info_signal_handler, old); +} + +static void +restore_termsig (sig, saved) + int sig; + const signal_info *saved; +{ + sigaction (sig, saved, NULL); +} +#else /* !HAVE_SIGACTION */ +typedef RETSIGTYPE (*signal_info) (); +#define set_termsig(sig, old) (void)(*(old) = signal (sig, info_signal_proc)) +#define restore_termsig(sig, saved) (void)signal (sig, *(saved)) +#define info_signal_handler info_signal_proc +static int term_conf_busy = 0; +#endif /* !HAVE_SIGACTION */ + +static signal_info old_TSTP, old_TTOU, old_TTIN; +static signal_info old_WINCH, old_INT, old_USR1, old_CONT; void initialize_info_signal_handler () { +#if defined (HAVE_SIGACTION) + info_signal_handler.sa_handler = info_signal_proc; + info_signal_handler.sa_flags = 0; + mask_termsig (&info_signal_handler.sa_mask); +#endif /* HAVE_SIGACTION */ + #if defined (SIGTSTP) - old_TSTP = (signal_handler *) signal (SIGTSTP, info_signal_handler); - old_TTOU = (signal_handler *) signal (SIGTTOU, info_signal_handler); - old_TTIN = (signal_handler *) signal (SIGTTIN, info_signal_handler); + set_termsig (SIGTSTP, &old_TSTP); + set_termsig (SIGTTOU, &old_TTOU); + set_termsig (SIGTTIN, &old_TTIN); #endif /* SIGTSTP */ #if defined (SIGWINCH) - old_WINCH = (signal_handler *) signal (SIGWINCH, info_signal_handler); + set_termsig (SIGWINCH, &old_WINCH); #if defined (SIGCONT) - old_CONT = (signal_handler *) signal (SIGCONT, info_signal_handler); + set_termsig (SIGCONT, &old_CONT); #endif #endif #if defined (SIGINT) - old_INT = (signal_handler *) signal (SIGINT, info_signal_handler); + set_termsig (SIGINT, &old_INT); #endif #if defined (SIGUSR1) /* Used by DJGPP to simulate SIGTSTP on Ctrl-Z. */ - old_USR1 = (signal_handler *) signal (SIGUSR1, info_signal_handler); + set_termsig (SIGUSR1, &old_USR1); #endif } @@ -121,11 +173,25 @@ reset_info_window_sizes () } static RETSIGTYPE -info_signal_handler (sig) +info_signal_proc (sig) int sig; { - signal_handler **old_signal_handler; + signal_info *old_signal_handler; +#if !defined (HAVE_SIGACTION) + /* best effort: first increment this counter and later block signals */ + if (term_conf_busy) + return; + term_conf_busy++; +#if defined (HAVE_SIGPROCMASK) || defined (HAVE_SIGSETMASK) + { + sigset_t nvar, ovar; + sigemptyset (&nvar); + mask_termsig (&nvar); + sigprocmask (SIG_BLOCK, &nvar, &ovar); + } +#endif /* HAVE_SIGPROCMASK || HAVE_SIGSETMASK */ +#endif /* !HAVE_SIGACTION */ switch (sig) { #if defined (SIGTSTP) @@ -145,8 +211,10 @@ info_signal_handler (sig) if (sig == SIGTTIN) old_signal_handler = &old_TTIN; #endif /* SIGTSTP */ +#if defined (SIGINT) if (sig == SIGINT) old_signal_handler = &old_INT; +#endif /* SIGINT */ /* For stop signals, restore the terminal IO, leave the cursor at the bottom of the window, and stop us. */ @@ -154,17 +222,17 @@ info_signal_handler (sig) terminal_clear_to_eol (); fflush (stdout); terminal_unprep_terminal (); - signal (sig, *old_signal_handler); - UNBLOCK_SIGNAL (sig); - kill (getpid (), sig); + restore_termsig (sig, old_signal_handler); + UNBLOCK_SIGNAL (sig); + kill (getpid (), sig); /* The program is returning now. Restore our signal handler, turn on terminal handling, redraw the screen, and place the cursor where it belongs. */ terminal_prep_terminal (); - *old_signal_handler = (signal_handler *) signal (sig, info_signal_handler); - redisplay_after_signal (); - fflush (stdout); + set_termsig (sig, old_signal_handler); + /* window size might be changed while sleeping */ + reset_info_window_sizes (); } break; @@ -182,39 +250,46 @@ info_signal_handler (sig) case SIGUSR1: #endif { - if (!in_sigwinch) { - in_sigwinch++; - - /* Turn off terminal IO, tell our parent that the window has changed, - then reinitialize the terminal and rebuild our windows. */ + /* Turn off terminal IO, tell our parent that the window has changed, + then reinitialize the terminal and rebuild our windows. */ #ifdef SIGWINCH - if (sig == SIGWINCH) - old_signal_handler = &old_WINCH; + if (sig == SIGWINCH) + old_signal_handler = &old_WINCH; #ifdef SIGCONT - else if (sig == SIGCONT) - old_signal_handler = &old_CONT; + else if (sig == SIGCONT) + old_signal_handler = &old_CONT; #endif #endif #ifdef SIGUSR1 - if (sig == SIGUSR1) - old_signal_handler = &old_USR1; + if (sig == SIGUSR1) + old_signal_handler = &old_USR1; #endif - terminal_goto_xy (0, 0); - fflush (stdout); - terminal_unprep_terminal (); - signal (sig, *old_signal_handler); - UNBLOCK_SIGNAL (sig); - kill (getpid (), sig); - - /* After our old signal handler returns... */ - *old_signal_handler - = (signal_handler *) signal (sig, info_signal_handler); - terminal_prep_terminal (); - reset_info_window_sizes (); - in_sigwinch--; - } + terminal_goto_xy (0, 0); + fflush (stdout); + terminal_unprep_terminal (); /* needless? */ + restore_termsig (sig, old_signal_handler); + UNBLOCK_SIGNAL (sig); + kill (getpid (), sig); + + /* After our old signal handler returns... */ + set_termsig (sig, old_signal_handler); /* needless? */ + terminal_prep_terminal (); + reset_info_window_sizes (); } break; #endif /* SIGWINCH || SIGUSR1 */ } +#if !defined (HAVE_SIGACTION) + /* at this time it is safer to perform unblock after decrement */ + term_conf_busy--; +#if defined (HAVE_SIGPROCMASK) || defined (HAVE_SIGSETMASK) + { + sigset_t nvar, ovar; + sigemptyset (&nvar); + mask_termsig (&nvar); + sigprocmask (SIG_UNBLOCK, &nvar, &ovar); + } +#endif /* HAVE_SIGPROCMASK || HAVE_SIGSETMASK */ +#endif /* !HAVE_SIGACTION */ } +/* vim: set sw=2 cino={1s>2sn-s^-se-s: */ |