1a5f0fb15SPaul Saab /* 2a5f0fb15SPaul Saab * Copyright (C) 1984-2000 Mark Nudelman 3a5f0fb15SPaul Saab * 4a5f0fb15SPaul Saab * You may distribute under the terms of either the GNU General Public 5a5f0fb15SPaul Saab * License or the Less License, as specified in the README file. 6a5f0fb15SPaul Saab * 7a5f0fb15SPaul Saab * For more information about less, or for information on how to 8a5f0fb15SPaul Saab * contact the author, see the README file. 9a5f0fb15SPaul Saab */ 10a5f0fb15SPaul Saab 1151525cb0SPaul Saab /* $FreeBSD$ */ 12a5f0fb15SPaul Saab 13a5f0fb15SPaul Saab /* 14a5f0fb15SPaul Saab * Routines dealing with signals. 15a5f0fb15SPaul Saab * 16a5f0fb15SPaul Saab * A signal usually merely causes a bit to be set in the "signals" word. 17a5f0fb15SPaul Saab * At some convenient time, the mainline code checks to see if any 18a5f0fb15SPaul Saab * signals need processing by calling psignal(). 19a5f0fb15SPaul Saab * If we happen to be reading from a file [in iread()] at the time 20a5f0fb15SPaul Saab * the signal is received, we call intread to interrupt the iread. 21a5f0fb15SPaul Saab */ 22a5f0fb15SPaul Saab 23a5f0fb15SPaul Saab #include "less.h" 24a5f0fb15SPaul Saab #include <signal.h> 25a5f0fb15SPaul Saab 26a5f0fb15SPaul Saab /* 27a5f0fb15SPaul Saab * "sigs" contains bits indicating signals which need to be processed. 28a5f0fb15SPaul Saab */ 29a5f0fb15SPaul Saab public int sigs; 30a5f0fb15SPaul Saab 31a5f0fb15SPaul Saab extern int sc_width, sc_height; 32a5f0fb15SPaul Saab extern int screen_trashed; 33a5f0fb15SPaul Saab extern int lnloop; 34a5f0fb15SPaul Saab extern int linenums; 35a5f0fb15SPaul Saab extern int wscroll; 36a5f0fb15SPaul Saab extern int reading; 3751525cb0SPaul Saab extern int more_mode; 38a5f0fb15SPaul Saab 39a5f0fb15SPaul Saab /* 40a5f0fb15SPaul Saab * Interrupt signal handler. 41a5f0fb15SPaul Saab */ 42a5f0fb15SPaul Saab /* ARGSUSED*/ 43a5f0fb15SPaul Saab static RETSIGTYPE 44a5f0fb15SPaul Saab u_interrupt(type) 45a5f0fb15SPaul Saab int type; 46a5f0fb15SPaul Saab { 47a5f0fb15SPaul Saab #if OS2 48a5f0fb15SPaul Saab LSIGNAL(SIGINT, SIG_ACK); 49a5f0fb15SPaul Saab #endif 50a5f0fb15SPaul Saab LSIGNAL(SIGINT, u_interrupt); 51a5f0fb15SPaul Saab sigs |= S_INTERRUPT; 52a5f0fb15SPaul Saab #if MSDOS_COMPILER==DJGPPC 53a5f0fb15SPaul Saab /* 54a5f0fb15SPaul Saab * If a keyboard has been hit, it must be Ctrl-C 55a5f0fb15SPaul Saab * (as opposed to Ctrl-Break), so consume it. 56a5f0fb15SPaul Saab * (Otherwise, Less will beep when it sees Ctrl-C from keyboard.) 57a5f0fb15SPaul Saab */ 58a5f0fb15SPaul Saab if (kbhit()) 59a5f0fb15SPaul Saab getkey(); 60a5f0fb15SPaul Saab #endif 6151525cb0SPaul Saab if (more_mode) 6251525cb0SPaul Saab quit(0); 63a5f0fb15SPaul Saab if (reading) 64a5f0fb15SPaul Saab intread(); 65a5f0fb15SPaul Saab } 66a5f0fb15SPaul Saab 67a5f0fb15SPaul Saab #ifdef SIGTSTP 68a5f0fb15SPaul Saab /* 69a5f0fb15SPaul Saab * "Stop" (^Z) signal handler. 70a5f0fb15SPaul Saab */ 71a5f0fb15SPaul Saab /* ARGSUSED*/ 72a5f0fb15SPaul Saab static RETSIGTYPE 73a5f0fb15SPaul Saab stop(type) 74a5f0fb15SPaul Saab int type; 75a5f0fb15SPaul Saab { 76a5f0fb15SPaul Saab LSIGNAL(SIGTSTP, stop); 77a5f0fb15SPaul Saab sigs |= S_STOP; 78a5f0fb15SPaul Saab if (reading) 79a5f0fb15SPaul Saab intread(); 80a5f0fb15SPaul Saab } 81a5f0fb15SPaul Saab #endif 82a5f0fb15SPaul Saab 83a5f0fb15SPaul Saab #ifdef SIGWINCH 84a5f0fb15SPaul Saab /* 85a5f0fb15SPaul Saab * "Window" change handler 86a5f0fb15SPaul Saab */ 87a5f0fb15SPaul Saab /* ARGSUSED*/ 88a5f0fb15SPaul Saab public RETSIGTYPE 89a5f0fb15SPaul Saab winch(type) 90a5f0fb15SPaul Saab int type; 91a5f0fb15SPaul Saab { 92a5f0fb15SPaul Saab LSIGNAL(SIGWINCH, winch); 93a5f0fb15SPaul Saab sigs |= S_WINCH; 94a5f0fb15SPaul Saab if (reading) 95a5f0fb15SPaul Saab intread(); 96a5f0fb15SPaul Saab } 97a5f0fb15SPaul Saab #else 98a5f0fb15SPaul Saab #ifdef SIGWIND 99a5f0fb15SPaul Saab /* 100a5f0fb15SPaul Saab * "Window" change handler 101a5f0fb15SPaul Saab */ 102a5f0fb15SPaul Saab /* ARGSUSED*/ 103a5f0fb15SPaul Saab public RETSIGTYPE 104a5f0fb15SPaul Saab winch(type) 105a5f0fb15SPaul Saab int type; 106a5f0fb15SPaul Saab { 107a5f0fb15SPaul Saab LSIGNAL(SIGWIND, winch); 108a5f0fb15SPaul Saab sigs |= S_WINCH; 109a5f0fb15SPaul Saab if (reading) 110a5f0fb15SPaul Saab intread(); 111a5f0fb15SPaul Saab } 112a5f0fb15SPaul Saab #endif 113a5f0fb15SPaul Saab #endif 114a5f0fb15SPaul Saab 115a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 116a5f0fb15SPaul Saab /* 117a5f0fb15SPaul Saab * Handle CTRL-C and CTRL-BREAK keys. 118a5f0fb15SPaul Saab */ 119a5f0fb15SPaul Saab #include "windows.h" 120a5f0fb15SPaul Saab 121a5f0fb15SPaul Saab static BOOL WINAPI 122a5f0fb15SPaul Saab wbreak_handler(dwCtrlType) 123a5f0fb15SPaul Saab DWORD dwCtrlType; 124a5f0fb15SPaul Saab { 125a5f0fb15SPaul Saab switch (dwCtrlType) 126a5f0fb15SPaul Saab { 127a5f0fb15SPaul Saab case CTRL_C_EVENT: 128a5f0fb15SPaul Saab case CTRL_BREAK_EVENT: 129a5f0fb15SPaul Saab sigs |= S_INTERRUPT; 130a5f0fb15SPaul Saab return (TRUE); 131a5f0fb15SPaul Saab default: 132a5f0fb15SPaul Saab break; 133a5f0fb15SPaul Saab } 134a5f0fb15SPaul Saab return (FALSE); 135a5f0fb15SPaul Saab } 136a5f0fb15SPaul Saab #endif 137a5f0fb15SPaul Saab 138a5f0fb15SPaul Saab /* 139a5f0fb15SPaul Saab * Set up the signal handlers. 140a5f0fb15SPaul Saab */ 141a5f0fb15SPaul Saab public void 142a5f0fb15SPaul Saab init_signals(on) 143a5f0fb15SPaul Saab int on; 144a5f0fb15SPaul Saab { 145a5f0fb15SPaul Saab if (on) 146a5f0fb15SPaul Saab { 147a5f0fb15SPaul Saab /* 148a5f0fb15SPaul Saab * Set signal handlers. 149a5f0fb15SPaul Saab */ 150a5f0fb15SPaul Saab (void) LSIGNAL(SIGINT, u_interrupt); 151a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 152a5f0fb15SPaul Saab SetConsoleCtrlHandler(wbreak_handler, TRUE); 153a5f0fb15SPaul Saab #endif 154a5f0fb15SPaul Saab #ifdef SIGTSTP 155a5f0fb15SPaul Saab (void) LSIGNAL(SIGTSTP, stop); 156a5f0fb15SPaul Saab #endif 157a5f0fb15SPaul Saab #ifdef SIGWINCH 158a5f0fb15SPaul Saab (void) LSIGNAL(SIGWINCH, winch); 159a5f0fb15SPaul Saab #else 160a5f0fb15SPaul Saab #ifdef SIGWIND 161a5f0fb15SPaul Saab (void) LSIGNAL(SIGWIND, winch); 162a5f0fb15SPaul Saab #endif 163a5f0fb15SPaul Saab #ifdef SIGQUIT 164a5f0fb15SPaul Saab (void) LSIGNAL(SIGQUIT, SIG_IGN); 165a5f0fb15SPaul Saab #endif 166a5f0fb15SPaul Saab #endif 167a5f0fb15SPaul Saab } else 168a5f0fb15SPaul Saab { 169a5f0fb15SPaul Saab /* 170a5f0fb15SPaul Saab * Restore signals to defaults. 171a5f0fb15SPaul Saab */ 172a5f0fb15SPaul Saab (void) LSIGNAL(SIGINT, SIG_DFL); 173a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 174a5f0fb15SPaul Saab SetConsoleCtrlHandler(wbreak_handler, FALSE); 175a5f0fb15SPaul Saab #endif 176a5f0fb15SPaul Saab #ifdef SIGTSTP 177a5f0fb15SPaul Saab (void) LSIGNAL(SIGTSTP, SIG_DFL); 178a5f0fb15SPaul Saab #endif 179a5f0fb15SPaul Saab #ifdef SIGWINCH 180a5f0fb15SPaul Saab (void) LSIGNAL(SIGWINCH, SIG_IGN); 181a5f0fb15SPaul Saab #endif 182a5f0fb15SPaul Saab #ifdef SIGWIND 183a5f0fb15SPaul Saab (void) LSIGNAL(SIGWIND, SIG_IGN); 184a5f0fb15SPaul Saab #endif 185a5f0fb15SPaul Saab #ifdef SIGQUIT 186a5f0fb15SPaul Saab (void) LSIGNAL(SIGQUIT, SIG_DFL); 187a5f0fb15SPaul Saab #endif 188a5f0fb15SPaul Saab } 189a5f0fb15SPaul Saab } 190a5f0fb15SPaul Saab 191a5f0fb15SPaul Saab /* 192a5f0fb15SPaul Saab * Process any signals we have received. 193a5f0fb15SPaul Saab * A received signal cause a bit to be set in "sigs". 194a5f0fb15SPaul Saab */ 195a5f0fb15SPaul Saab public void 196a5f0fb15SPaul Saab psignals() 197a5f0fb15SPaul Saab { 198a5f0fb15SPaul Saab register int tsignals; 199a5f0fb15SPaul Saab 200a5f0fb15SPaul Saab if ((tsignals = sigs) == 0) 201a5f0fb15SPaul Saab return; 202a5f0fb15SPaul Saab sigs = 0; 203a5f0fb15SPaul Saab 204a5f0fb15SPaul Saab #ifdef SIGTSTP 205a5f0fb15SPaul Saab if (tsignals & S_STOP) 206a5f0fb15SPaul Saab { 207a5f0fb15SPaul Saab /* 208a5f0fb15SPaul Saab * Clean up the terminal. 209a5f0fb15SPaul Saab */ 210a5f0fb15SPaul Saab #ifdef SIGTTOU 211a5f0fb15SPaul Saab LSIGNAL(SIGTTOU, SIG_IGN); 212a5f0fb15SPaul Saab #endif 213a5f0fb15SPaul Saab clear_bot(); 214a5f0fb15SPaul Saab deinit(); 215a5f0fb15SPaul Saab flush(); 216a5f0fb15SPaul Saab raw_mode(0); 217a5f0fb15SPaul Saab #ifdef SIGTTOU 218a5f0fb15SPaul Saab LSIGNAL(SIGTTOU, SIG_DFL); 219a5f0fb15SPaul Saab #endif 220a5f0fb15SPaul Saab LSIGNAL(SIGTSTP, SIG_DFL); 221a5f0fb15SPaul Saab kill(getpid(), SIGTSTP); 222a5f0fb15SPaul Saab /* 223a5f0fb15SPaul Saab * ... Bye bye. ... 224a5f0fb15SPaul Saab * Hopefully we'll be back later and resume here... 225a5f0fb15SPaul Saab * Reset the terminal and arrange to repaint the 226a5f0fb15SPaul Saab * screen when we get back to the main command loop. 227a5f0fb15SPaul Saab */ 228a5f0fb15SPaul Saab LSIGNAL(SIGTSTP, stop); 229a5f0fb15SPaul Saab raw_mode(1); 230a5f0fb15SPaul Saab init(); 231a5f0fb15SPaul Saab screen_trashed = 1; 232a5f0fb15SPaul Saab tsignals |= S_WINCH; 233a5f0fb15SPaul Saab } 234a5f0fb15SPaul Saab #endif 235a5f0fb15SPaul Saab #ifdef S_WINCH 236a5f0fb15SPaul Saab if (tsignals & S_WINCH) 237a5f0fb15SPaul Saab { 238a5f0fb15SPaul Saab int old_width, old_height; 239a5f0fb15SPaul Saab /* 240a5f0fb15SPaul Saab * Re-execute scrsize() to read the new window size. 241a5f0fb15SPaul Saab */ 242a5f0fb15SPaul Saab old_width = sc_width; 243a5f0fb15SPaul Saab old_height = sc_height; 244a5f0fb15SPaul Saab get_term(); 245a5f0fb15SPaul Saab if (sc_width != old_width || sc_height != old_height) 246a5f0fb15SPaul Saab { 247a5f0fb15SPaul Saab wscroll = (sc_height + 1) / 2; 248a5f0fb15SPaul Saab screen_trashed = 1; 249a5f0fb15SPaul Saab } 250a5f0fb15SPaul Saab } 251a5f0fb15SPaul Saab #endif 252a5f0fb15SPaul Saab if (tsignals & S_INTERRUPT) 253a5f0fb15SPaul Saab { 254a5f0fb15SPaul Saab bell(); 255a5f0fb15SPaul Saab /* 256a5f0fb15SPaul Saab * {{ You may wish to replace the bell() with 257a5f0fb15SPaul Saab * error("Interrupt", NULL_PARG); }} 258a5f0fb15SPaul Saab */ 259a5f0fb15SPaul Saab 260a5f0fb15SPaul Saab /* 261a5f0fb15SPaul Saab * If we were interrupted while in the "calculating 262a5f0fb15SPaul Saab * line numbers" loop, turn off line numbers. 263a5f0fb15SPaul Saab */ 264a5f0fb15SPaul Saab if (lnloop) 265a5f0fb15SPaul Saab { 266a5f0fb15SPaul Saab lnloop = 0; 267a5f0fb15SPaul Saab if (linenums == 2) 268a5f0fb15SPaul Saab screen_trashed = 1; 269a5f0fb15SPaul Saab linenums = 0; 270a5f0fb15SPaul Saab error("Line numbers turned off", NULL_PARG); 271a5f0fb15SPaul Saab } 272a5f0fb15SPaul Saab 273a5f0fb15SPaul Saab } 274a5f0fb15SPaul Saab } 275