signals.c revision 21496
1219820Sjeff/* signals.c -- Install and maintain Info signal handlers. */ 2219820Sjeff 3219820Sjeff/* This file is part of GNU Info, a program for reading online documentation 4219820Sjeff stored in Info format. 5219820Sjeff 6219820Sjeff Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. 7219820Sjeff 8219820Sjeff This program is free software; you can redistribute it and/or modify 9219820Sjeff it under the terms of the GNU General Public License as published by 10219820Sjeff the Free Software Foundation; either version 2, or (at your option) 11219820Sjeff any later version. 12219820Sjeff 13219820Sjeff This program is distributed in the hope that it will be useful, 14219820Sjeff but WITHOUT ANY WARRANTY; without even the implied warranty of 15219820Sjeff MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16219820Sjeff GNU General Public License for more details. 17219820Sjeff 18219820Sjeff You should have received a copy of the GNU General Public License 19219820Sjeff along with this program; if not, write to the Free Software 20219820Sjeff Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21219820Sjeff 22219820Sjeff Written by Brian Fox (bfox@ai.mit.edu). */ 23219820Sjeff 24219820Sjeff#include "info.h" 25219820Sjeff#include "signals.h" 26219820Sjeff 27219820Sjeff/* **************************************************************** */ 28219820Sjeff/* */ 29219820Sjeff/* Pretending That We Have POSIX Signals */ 30219820Sjeff/* */ 31219820Sjeff/* **************************************************************** */ 32219820Sjeff 33219820Sjeff#if !defined (HAVE_SIGPROCMASK) && defined (HAVE_SIGSETMASK) 34219820Sjeff/* Perform OPERATION on NEWSET, perhaps leaving information in OLDSET. */ 35219820Sjeffstatic void 36219820Sjeffsigprocmask (operation, newset, oldset) 37219820Sjeff int operation, *newset, *oldset; 38219820Sjeff{ 39219820Sjeff switch (operation) 40219820Sjeff { 41219820Sjeff case SIG_UNBLOCK: 42219820Sjeff sigsetmask (sigblock (0) & ~(*newset)); 43219820Sjeff break; 44219820Sjeff 45219820Sjeff case SIG_BLOCK: 46219820Sjeff *oldset = sigblock (*newset); 47219820Sjeff break; 48219820Sjeff 49219820Sjeff case SIG_SETMASK: 50219820Sjeff sigsetmask (*newset); 51219820Sjeff break; 52219820Sjeff 53219820Sjeff default: 54219820Sjeff abort (); 55219820Sjeff } 56219820Sjeff} 57219820Sjeff#endif /* !HAVE_SIGPROCMASK && HAVE_SIGSETMASK */ 58219820Sjeff 59219820Sjeff/* **************************************************************** */ 60219820Sjeff/* */ 61219820Sjeff/* Signal Handling for Info */ 62219820Sjeff/* */ 63219820Sjeff/* **************************************************************** */ 64219820Sjeff 65219820Sjefftypedef void SigHandlerType; 66219820Sjefftypedef SigHandlerType SigHandler (); 67219820Sjeff 68219820Sjeffstatic SigHandlerType info_signal_handler (); 69219820Sjeffstatic SigHandler *old_TSTP, *old_TTOU, *old_TTIN; 70219820Sjeffstatic SigHandler *old_WINCH, *old_INT; 71219820Sjeff 72219820Sjeffvoid 73219820Sjeffinitialize_info_signal_handler () 74219820Sjeff{ 75219820Sjeff#if defined (SIGTSTP) 76219820Sjeff old_TSTP = (SigHandler *) signal (SIGTSTP, info_signal_handler); 77219820Sjeff old_TTOU = (SigHandler *) signal (SIGTTOU, info_signal_handler); 78219820Sjeff old_TTIN = (SigHandler *) signal (SIGTTIN, info_signal_handler); 79219820Sjeff#endif /* SIGTSTP */ 80219820Sjeff 81219820Sjeff#if defined (SIGWINCH) 82219820Sjeff old_WINCH = (SigHandler *) signal (SIGWINCH, info_signal_handler); 83219820Sjeff#endif 84219820Sjeff 85219820Sjeff#if defined (SIGINT) 86219820Sjeff old_INT = (SigHandler *) signal (SIGINT, info_signal_handler); 87219820Sjeff#endif 88219820Sjeff} 89219820Sjeff 90219820Sjeffstatic void 91219820Sjeffredisplay_after_signal () 92219820Sjeff{ 93219820Sjeff terminal_clear_screen (); 94219820Sjeff display_clear_display (the_display); 95219820Sjeff window_mark_chain (windows, W_UpdateWindow); 96219820Sjeff display_update_display (windows); 97219820Sjeff display_cursor_at_point (active_window); 98219820Sjeff fflush (stdout); 99219820Sjeff} 100219820Sjeff 101219820Sjeffstatic SigHandlerType 102219820Sjeffinfo_signal_handler (sig) 103219820Sjeff int sig; 104219820Sjeff{ 105219820Sjeff SigHandler **old_signal_handler; 106219820Sjeff 107219820Sjeff switch (sig) 108219820Sjeff { 109219820Sjeff#if defined (SIGTSTP) 110219820Sjeff case SIGTSTP: 111219820Sjeff case SIGTTOU: 112219820Sjeff case SIGTTIN: 113219820Sjeff#endif 114219820Sjeff#if defined (SIGINT) 115219820Sjeff case SIGINT: 116219820Sjeff#endif 117219820Sjeff { 118219820Sjeff#if defined (SIGTSTP) 119219820Sjeff if (sig == SIGTSTP) 120219820Sjeff old_signal_handler = &old_TSTP; 121219820Sjeff if (sig == SIGTTOU) 122219820Sjeff old_signal_handler = &old_TTOU; 123219820Sjeff if (sig == SIGTTIN) 124219820Sjeff old_signal_handler = &old_TTIN; 125219820Sjeff#endif /* SIGTSTP */ 126219820Sjeff if (sig == SIGINT) 127219820Sjeff old_signal_handler = &old_INT; 128219820Sjeff 129219820Sjeff /* For stop signals, restore the terminal IO, leave the cursor 130219820Sjeff at the bottom of the window, and stop us. */ 131219820Sjeff terminal_goto_xy (0, screenheight - 1); 132219820Sjeff terminal_clear_to_eol (); 133219820Sjeff fflush (stdout); 134219820Sjeff terminal_unprep_terminal (); 135219820Sjeff signal (sig, *old_signal_handler); 136219820Sjeff UNBLOCK_SIGNAL (sig); 137219820Sjeff kill (getpid (), sig); 138219820Sjeff 139219820Sjeff /* The program is returning now. Restore our signal handler, 140219820Sjeff turn on terminal handling, redraw the screen, and place the 141219820Sjeff cursor where it belongs. */ 142219820Sjeff terminal_prep_terminal (); 143219820Sjeff *old_signal_handler = (SigHandler *) signal (sig, info_signal_handler); 144219820Sjeff redisplay_after_signal (); 145219820Sjeff fflush (stdout); 146219820Sjeff } 147219820Sjeff break; 148219820Sjeff 149219820Sjeff#if defined (SIGWINCH) 150219820Sjeff case SIGWINCH: 151219820Sjeff { 152219820Sjeff /* Turn off terminal IO, tell our parent that the window has changed, 153219820Sjeff then reinitialize the terminal and rebuild our windows. */ 154243882Sglebius old_signal_handler = &old_WINCH; 155219820Sjeff terminal_goto_xy (0, 0); 156219820Sjeff fflush (stdout); 157219820Sjeff terminal_unprep_terminal (); 158219820Sjeff signal (sig, *old_signal_handler); 159219820Sjeff UNBLOCK_SIGNAL (sig); 160219820Sjeff kill (getpid (), sig); 161219820Sjeff 162219820Sjeff /* After our old signal handler returns... */ 163219820Sjeff terminal_get_screen_size (); 164219820Sjeff terminal_prep_terminal (); 165219820Sjeff display_initialize_display (screenwidth, screenheight); 166219820Sjeff window_new_screen_size (screenwidth, screenheight, (VFunction *)NULL); 167219820Sjeff *old_signal_handler = (SigHandler *) signal (sig, info_signal_handler); 168219820Sjeff redisplay_after_signal (); 169219820Sjeff } 170219820Sjeff break; 171219820Sjeff#endif /* SIGWINCH */ 172219820Sjeff } 173219820Sjeff} 174219820Sjeff