signals.c revision 116535
156165Sru/* signals.c -- install and maintain Info signal handlers. 2114478Sru $Id: signals.c,v 1.4 2003/01/29 19:23:22 karl Exp $ 321495Sjmacd 4114478Sru Copyright (C) 1993, 1994, 1995, 1998, 2002, 2003 Free Software 5114478Sru Foundation, Inc. 621495Sjmacd 721495Sjmacd This program is free software; you can redistribute it and/or modify 821495Sjmacd it under the terms of the GNU General Public License as published by 921495Sjmacd the Free Software Foundation; either version 2, or (at your option) 1021495Sjmacd any later version. 1121495Sjmacd 1221495Sjmacd This program is distributed in the hope that it will be useful, 1321495Sjmacd but WITHOUT ANY WARRANTY; without even the implied warranty of 1421495Sjmacd MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1521495Sjmacd GNU General Public License for more details. 1621495Sjmacd 1721495Sjmacd You should have received a copy of the GNU General Public License 1821495Sjmacd along with this program; if not, write to the Free Software 1921495Sjmacd Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 2021495Sjmacd 2121495Sjmacd Written by Brian Fox (bfox@ai.mit.edu). */ 2221495Sjmacd 2321495Sjmacd#include "info.h" 2421495Sjmacd#include "signals.h" 2521495Sjmacd 2621495Sjmacd/* **************************************************************** */ 2742664Smarkm/* */ 2842664Smarkm/* Pretending That We Have POSIX Signals */ 2942664Smarkm/* */ 3021495Sjmacd/* **************************************************************** */ 3121495Sjmacd 3221495Sjmacd#if !defined (HAVE_SIGPROCMASK) && defined (HAVE_SIGSETMASK) 3321495Sjmacd/* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */ 3421495Sjmacdstatic void 3521495Sjmacdsigprocmask (operation, newset, oldset) 3621495Sjmacd int operation, *newset, *oldset; 3721495Sjmacd{ 3821495Sjmacd switch (operation) 3921495Sjmacd { 4021495Sjmacd case SIG_UNBLOCK: 4121495Sjmacd sigsetmask (sigblock (0) & ~(*newset)); 4221495Sjmacd break; 4321495Sjmacd 4421495Sjmacd case SIG_BLOCK: 4521495Sjmacd *oldset = sigblock (*newset); 4621495Sjmacd break; 4721495Sjmacd 4821495Sjmacd case SIG_SETMASK: 4921495Sjmacd sigsetmask (*newset); 5021495Sjmacd break; 5121495Sjmacd 5221495Sjmacd default: 5321495Sjmacd abort (); 5421495Sjmacd } 5521495Sjmacd} 5621495Sjmacd#endif /* !HAVE_SIGPROCMASK && HAVE_SIGSETMASK */ 5721495Sjmacd 5821495Sjmacd/* **************************************************************** */ 5942664Smarkm/* */ 6042664Smarkm/* Signal Handling for Info */ 6142664Smarkm/* */ 6221495Sjmacd/* **************************************************************** */ 6321495Sjmacd 64114478Sru#if defined (HAVE_SIGACTION) || defined (HAVE_SIGPROCMASK) ||\ 65114478Sru defined (HAVE_SIGSETMASK) 66114478Srustatic void 67114478Srumask_termsig (set) 68114478Sru sigset_t *set; 69114478Sru{ 70114478Sru# if defined (SIGTSTP) 71114478Sru sigaddset (set, SIGTSTP); 72114478Sru sigaddset (set, SIGTTOU); 73114478Sru sigaddset (set, SIGTTIN); 74114478Sru# endif 75114478Sru# if defined (SIGWINCH) 76114478Sru sigaddset (set, SIGWINCH); 77114478Sru# endif 78114478Sru#if defined (SIGINT) 79114478Sru sigaddset (set, SIGINT); 80114478Sru#endif 81114478Sru# if defined (SIGUSR1) 82114478Sru sigaddset (set, SIGUSR1); 83114478Sru# endif 84114478Sru} 85114478Sru#endif /* HAVE_SIGACTION || HAVE_SIGPROCMASK || HAVE_SIGSETMASK */ 8621495Sjmacd 87114478Srustatic RETSIGTYPE info_signal_proc (); 88114478Sru#if defined (HAVE_SIGACTION) 89114478Srutypedef struct sigaction signal_info; 90114478Srusignal_info info_signal_handler; 9121495Sjmacd 92114478Srustatic void 93114478Sruset_termsig (sig, old) 94114478Sru int sig; 95114478Sru signal_info *old; 96114478Sru{ 97114478Sru sigaction (sig, &info_signal_handler, old); 98114478Sru} 99114478Sru 100114478Srustatic void 101114478Srurestore_termsig (sig, saved) 102114478Sru int sig; 103114478Sru const signal_info *saved; 104114478Sru{ 105114478Sru sigaction (sig, saved, NULL); 106114478Sru} 107114478Sru#else /* !HAVE_SIGACTION */ 108114478Srutypedef RETSIGTYPE (*signal_info) (); 109114478Sru#define set_termsig(sig, old) (void)(*(old) = signal (sig, info_signal_proc)) 110114478Sru#define restore_termsig(sig, saved) (void)signal (sig, *(saved)) 111114478Sru#define info_signal_handler info_signal_proc 112114478Srustatic int term_conf_busy = 0; 113114478Sru#endif /* !HAVE_SIGACTION */ 114114478Sru 115114478Srustatic signal_info old_TSTP, old_TTOU, old_TTIN; 116116535Srustatic signal_info old_WINCH, old_INT, old_USR1; 117114478Sru 11821495Sjmacdvoid 11921495Sjmacdinitialize_info_signal_handler () 12021495Sjmacd{ 121114478Sru#if defined (HAVE_SIGACTION) 122114478Sru info_signal_handler.sa_handler = info_signal_proc; 123114478Sru info_signal_handler.sa_flags = 0; 124114478Sru mask_termsig (&info_signal_handler.sa_mask); 125114478Sru#endif /* HAVE_SIGACTION */ 126114478Sru 12721495Sjmacd#if defined (SIGTSTP) 128114478Sru set_termsig (SIGTSTP, &old_TSTP); 129114478Sru set_termsig (SIGTTOU, &old_TTOU); 130114478Sru set_termsig (SIGTTIN, &old_TTIN); 13121495Sjmacd#endif /* SIGTSTP */ 13221495Sjmacd 13321495Sjmacd#if defined (SIGWINCH) 134114478Sru set_termsig (SIGWINCH, &old_WINCH); 13542664Smarkm#endif 13621495Sjmacd 13721495Sjmacd#if defined (SIGINT) 138114478Sru set_termsig (SIGINT, &old_INT); 13921495Sjmacd#endif 14056165Sru 14156165Sru#if defined (SIGUSR1) 14256165Sru /* Used by DJGPP to simulate SIGTSTP on Ctrl-Z. */ 143114478Sru set_termsig (SIGUSR1, &old_USR1); 14456165Sru#endif 14521495Sjmacd} 14621495Sjmacd 14721495Sjmacdstatic void 14821495Sjmacdredisplay_after_signal () 14921495Sjmacd{ 15021495Sjmacd terminal_clear_screen (); 15121495Sjmacd display_clear_display (the_display); 15221495Sjmacd window_mark_chain (windows, W_UpdateWindow); 15321495Sjmacd display_update_display (windows); 15421495Sjmacd display_cursor_at_point (active_window); 15521495Sjmacd fflush (stdout); 15621495Sjmacd} 15721495Sjmacd 15856165Srustatic void 15956165Srureset_info_window_sizes () 16056165Sru{ 16156165Sru terminal_goto_xy (0, 0); 16256165Sru fflush (stdout); 16356165Sru terminal_unprep_terminal (); 16456165Sru terminal_get_screen_size (); 16556165Sru terminal_prep_terminal (); 16656165Sru display_initialize_display (screenwidth, screenheight); 16756165Sru window_new_screen_size (screenwidth, screenheight, NULL); 16856165Sru redisplay_after_signal (); 16956165Sru} 17056165Sru 17142664Smarkmstatic RETSIGTYPE 172114478Sruinfo_signal_proc (sig) 17321495Sjmacd int sig; 17421495Sjmacd{ 175114478Sru signal_info *old_signal_handler; 17621495Sjmacd 177114478Sru#if !defined (HAVE_SIGACTION) 178114478Sru /* best effort: first increment this counter and later block signals */ 179114478Sru if (term_conf_busy) 180114478Sru return; 181114478Sru term_conf_busy++; 182114478Sru#if defined (HAVE_SIGPROCMASK) || defined (HAVE_SIGSETMASK) 183114478Sru { 184114478Sru sigset_t nvar, ovar; 185114478Sru sigemptyset (&nvar); 186114478Sru mask_termsig (&nvar); 187114478Sru sigprocmask (SIG_BLOCK, &nvar, &ovar); 188114478Sru } 189114478Sru#endif /* HAVE_SIGPROCMASK || HAVE_SIGSETMASK */ 190114478Sru#endif /* !HAVE_SIGACTION */ 19121495Sjmacd switch (sig) 19221495Sjmacd { 19321495Sjmacd#if defined (SIGTSTP) 19421495Sjmacd case SIGTSTP: 19521495Sjmacd case SIGTTOU: 19621495Sjmacd case SIGTTIN: 19721495Sjmacd#endif 19821495Sjmacd#if defined (SIGINT) 19921495Sjmacd case SIGINT: 20021495Sjmacd#endif 20121495Sjmacd { 20221495Sjmacd#if defined (SIGTSTP) 20342664Smarkm if (sig == SIGTSTP) 20442664Smarkm old_signal_handler = &old_TSTP; 20542664Smarkm if (sig == SIGTTOU) 20642664Smarkm old_signal_handler = &old_TTOU; 20742664Smarkm if (sig == SIGTTIN) 20842664Smarkm old_signal_handler = &old_TTIN; 20921495Sjmacd#endif /* SIGTSTP */ 210114478Sru#if defined (SIGINT) 21142664Smarkm if (sig == SIGINT) 21242664Smarkm old_signal_handler = &old_INT; 213114478Sru#endif /* SIGINT */ 21421495Sjmacd 21542664Smarkm /* For stop signals, restore the terminal IO, leave the cursor 21642664Smarkm at the bottom of the window, and stop us. */ 21742664Smarkm terminal_goto_xy (0, screenheight - 1); 21842664Smarkm terminal_clear_to_eol (); 21942664Smarkm fflush (stdout); 22042664Smarkm terminal_unprep_terminal (); 221114478Sru restore_termsig (sig, old_signal_handler); 222114478Sru UNBLOCK_SIGNAL (sig); 223114478Sru kill (getpid (), sig); 22421495Sjmacd 22542664Smarkm /* The program is returning now. Restore our signal handler, 22642664Smarkm turn on terminal handling, redraw the screen, and place the 22742664Smarkm cursor where it belongs. */ 22842664Smarkm terminal_prep_terminal (); 229114478Sru set_termsig (sig, old_signal_handler); 230114478Sru /* window size might be changed while sleeping */ 231114478Sru reset_info_window_sizes (); 23221495Sjmacd } 23321495Sjmacd break; 23421495Sjmacd 23556165Sru#if defined (SIGWINCH) || defined (SIGUSR1) 23656165Sru#ifdef SIGWINCH 23721495Sjmacd case SIGWINCH: 23856165Sru#endif 23956165Sru#ifdef SIGUSR1 24056165Sru case SIGUSR1: 24156165Sru#endif 24221495Sjmacd { 243114478Sru /* Turn off terminal IO, tell our parent that the window has changed, 244114478Sru then reinitialize the terminal and rebuild our windows. */ 24556165Sru#ifdef SIGWINCH 246114478Sru if (sig == SIGWINCH) 247114478Sru old_signal_handler = &old_WINCH; 24856165Sru#endif 24956165Sru#ifdef SIGUSR1 250114478Sru if (sig == SIGUSR1) 251114478Sru old_signal_handler = &old_USR1; 25256165Sru#endif 253114478Sru terminal_goto_xy (0, 0); 254114478Sru fflush (stdout); 255114478Sru terminal_unprep_terminal (); /* needless? */ 256114478Sru restore_termsig (sig, old_signal_handler); 257114478Sru UNBLOCK_SIGNAL (sig); 258114478Sru kill (getpid (), sig); 25921495Sjmacd 260114478Sru /* After our old signal handler returns... */ 261114478Sru set_termsig (sig, old_signal_handler); /* needless? */ 262114478Sru terminal_prep_terminal (); 263114478Sru reset_info_window_sizes (); 26421495Sjmacd } 26521495Sjmacd break; 26656165Sru#endif /* SIGWINCH || SIGUSR1 */ 26721495Sjmacd } 268114478Sru#if !defined (HAVE_SIGACTION) 269114478Sru /* at this time it is safer to perform unblock after decrement */ 270114478Sru term_conf_busy--; 271114478Sru#if defined (HAVE_SIGPROCMASK) || defined (HAVE_SIGSETMASK) 272114478Sru { 273114478Sru sigset_t nvar, ovar; 274114478Sru sigemptyset (&nvar); 275114478Sru mask_termsig (&nvar); 276114478Sru sigprocmask (SIG_UNBLOCK, &nvar, &ovar); 277114478Sru } 278114478Sru#endif /* HAVE_SIGPROCMASK || HAVE_SIGSETMASK */ 279114478Sru#endif /* !HAVE_SIGACTION */ 28021495Sjmacd} 281114478Sru/* vim: set sw=2 cino={1s>2sn-s^-se-s: */ 282