1a5f0fb15SPaul Saab /* 27374caaaSXin LI * Copyright (C) 1984-2008 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; 3789dd99dcSXin LI extern int quit_on_intr; 38720c436cSXin LI extern int less_is_more; 39720c436cSXin LI extern long jump_sline_fraction; 40a5f0fb15SPaul Saab 41a5f0fb15SPaul Saab /* 42a5f0fb15SPaul Saab * Interrupt signal handler. 43a5f0fb15SPaul Saab */ 44a5f0fb15SPaul Saab /* ARGSUSED*/ 45a5f0fb15SPaul Saab static RETSIGTYPE 46a5f0fb15SPaul Saab u_interrupt(type) 47a5f0fb15SPaul Saab int type; 48a5f0fb15SPaul Saab { 497374caaaSXin LI bell(); 50a5f0fb15SPaul Saab #if OS2 51a5f0fb15SPaul Saab LSIGNAL(SIGINT, SIG_ACK); 52a5f0fb15SPaul Saab #endif 53a5f0fb15SPaul Saab LSIGNAL(SIGINT, u_interrupt); 54a5f0fb15SPaul Saab sigs |= S_INTERRUPT; 55a5f0fb15SPaul Saab #if MSDOS_COMPILER==DJGPPC 56a5f0fb15SPaul Saab /* 57a5f0fb15SPaul Saab * If a keyboard has been hit, it must be Ctrl-C 58a5f0fb15SPaul Saab * (as opposed to Ctrl-Break), so consume it. 59a5f0fb15SPaul Saab * (Otherwise, Less will beep when it sees Ctrl-C from keyboard.) 60a5f0fb15SPaul Saab */ 61a5f0fb15SPaul Saab if (kbhit()) 62a5f0fb15SPaul Saab getkey(); 63a5f0fb15SPaul Saab #endif 64720c436cSXin LI if (less_is_more) 6551525cb0SPaul Saab quit(0); 66a5f0fb15SPaul Saab if (reading) 677374caaaSXin LI intread(); /* May longjmp */ 68a5f0fb15SPaul Saab } 69a5f0fb15SPaul Saab 70a5f0fb15SPaul Saab #ifdef SIGTSTP 71a5f0fb15SPaul Saab /* 72a5f0fb15SPaul Saab * "Stop" (^Z) signal handler. 73a5f0fb15SPaul Saab */ 74a5f0fb15SPaul Saab /* ARGSUSED*/ 75a5f0fb15SPaul Saab static RETSIGTYPE 76a5f0fb15SPaul Saab stop(type) 77a5f0fb15SPaul Saab int type; 78a5f0fb15SPaul Saab { 79a5f0fb15SPaul Saab LSIGNAL(SIGTSTP, stop); 80a5f0fb15SPaul Saab sigs |= S_STOP; 81a5f0fb15SPaul Saab if (reading) 82a5f0fb15SPaul Saab intread(); 83a5f0fb15SPaul Saab } 84a5f0fb15SPaul Saab #endif 85a5f0fb15SPaul Saab 86a5f0fb15SPaul Saab #ifdef SIGWINCH 87a5f0fb15SPaul Saab /* 88a5f0fb15SPaul Saab * "Window" change handler 89a5f0fb15SPaul Saab */ 90a5f0fb15SPaul Saab /* ARGSUSED*/ 91a5f0fb15SPaul Saab public RETSIGTYPE 92a5f0fb15SPaul Saab winch(type) 93a5f0fb15SPaul Saab int type; 94a5f0fb15SPaul Saab { 95a5f0fb15SPaul Saab LSIGNAL(SIGWINCH, winch); 96a5f0fb15SPaul Saab sigs |= S_WINCH; 9759a2d077SXin LI if (reading) 9859a2d077SXin LI intread(); 99a5f0fb15SPaul Saab } 100a5f0fb15SPaul Saab #else 101a5f0fb15SPaul Saab #ifdef SIGWIND 102a5f0fb15SPaul Saab /* 103a5f0fb15SPaul Saab * "Window" change handler 104a5f0fb15SPaul Saab */ 105a5f0fb15SPaul Saab /* ARGSUSED*/ 106a5f0fb15SPaul Saab public RETSIGTYPE 107a5f0fb15SPaul Saab winch(type) 108a5f0fb15SPaul Saab int type; 109a5f0fb15SPaul Saab { 110a5f0fb15SPaul Saab LSIGNAL(SIGWIND, winch); 111a5f0fb15SPaul Saab sigs |= S_WINCH; 112a5f0fb15SPaul Saab if (reading) 113a5f0fb15SPaul Saab intread(); 114a5f0fb15SPaul Saab } 115a5f0fb15SPaul Saab #endif 116a5f0fb15SPaul Saab #endif 117a5f0fb15SPaul Saab 118a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 119a5f0fb15SPaul Saab /* 120a5f0fb15SPaul Saab * Handle CTRL-C and CTRL-BREAK keys. 121a5f0fb15SPaul Saab */ 122a5f0fb15SPaul Saab #include "windows.h" 123a5f0fb15SPaul Saab 124a5f0fb15SPaul Saab static BOOL WINAPI 125a5f0fb15SPaul Saab wbreak_handler(dwCtrlType) 126a5f0fb15SPaul Saab DWORD dwCtrlType; 127a5f0fb15SPaul Saab { 128a5f0fb15SPaul Saab switch (dwCtrlType) 129a5f0fb15SPaul Saab { 130a5f0fb15SPaul Saab case CTRL_C_EVENT: 131a5f0fb15SPaul Saab case CTRL_BREAK_EVENT: 132a5f0fb15SPaul Saab sigs |= S_INTERRUPT; 133a5f0fb15SPaul Saab return (TRUE); 134a5f0fb15SPaul Saab default: 135a5f0fb15SPaul Saab break; 136a5f0fb15SPaul Saab } 137a5f0fb15SPaul Saab return (FALSE); 138a5f0fb15SPaul Saab } 139a5f0fb15SPaul Saab #endif 140a5f0fb15SPaul Saab 141a5f0fb15SPaul Saab /* 142a5f0fb15SPaul Saab * Set up the signal handlers. 143a5f0fb15SPaul Saab */ 144a5f0fb15SPaul Saab public void 145a5f0fb15SPaul Saab init_signals(on) 146a5f0fb15SPaul Saab int on; 147a5f0fb15SPaul Saab { 148a5f0fb15SPaul Saab if (on) 149a5f0fb15SPaul Saab { 150a5f0fb15SPaul Saab /* 151a5f0fb15SPaul Saab * Set signal handlers. 152a5f0fb15SPaul Saab */ 153a5f0fb15SPaul Saab (void) LSIGNAL(SIGINT, u_interrupt); 154a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 155a5f0fb15SPaul Saab SetConsoleCtrlHandler(wbreak_handler, TRUE); 156a5f0fb15SPaul Saab #endif 157a5f0fb15SPaul Saab #ifdef SIGTSTP 158a5f0fb15SPaul Saab (void) LSIGNAL(SIGTSTP, stop); 159a5f0fb15SPaul Saab #endif 160a5f0fb15SPaul Saab #ifdef SIGWINCH 161a5f0fb15SPaul Saab (void) LSIGNAL(SIGWINCH, winch); 162720c436cSXin LI #endif 163a5f0fb15SPaul Saab #ifdef SIGWIND 164a5f0fb15SPaul Saab (void) LSIGNAL(SIGWIND, winch); 165a5f0fb15SPaul Saab #endif 166a5f0fb15SPaul Saab #ifdef SIGQUIT 167a5f0fb15SPaul Saab (void) LSIGNAL(SIGQUIT, SIG_IGN); 168a5f0fb15SPaul Saab #endif 169a5f0fb15SPaul Saab } else 170a5f0fb15SPaul Saab { 171a5f0fb15SPaul Saab /* 172a5f0fb15SPaul Saab * Restore signals to defaults. 173a5f0fb15SPaul Saab */ 174a5f0fb15SPaul Saab (void) LSIGNAL(SIGINT, SIG_DFL); 175a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 176a5f0fb15SPaul Saab SetConsoleCtrlHandler(wbreak_handler, FALSE); 177a5f0fb15SPaul Saab #endif 178a5f0fb15SPaul Saab #ifdef SIGTSTP 179a5f0fb15SPaul Saab (void) LSIGNAL(SIGTSTP, SIG_DFL); 180a5f0fb15SPaul Saab #endif 181a5f0fb15SPaul Saab #ifdef SIGWINCH 182a5f0fb15SPaul Saab (void) LSIGNAL(SIGWINCH, SIG_IGN); 183a5f0fb15SPaul Saab #endif 184a5f0fb15SPaul Saab #ifdef SIGWIND 185a5f0fb15SPaul Saab (void) LSIGNAL(SIGWIND, SIG_IGN); 186a5f0fb15SPaul Saab #endif 187a5f0fb15SPaul Saab #ifdef SIGQUIT 188a5f0fb15SPaul Saab (void) LSIGNAL(SIGQUIT, SIG_DFL); 189a5f0fb15SPaul Saab #endif 190a5f0fb15SPaul Saab } 191a5f0fb15SPaul Saab } 192a5f0fb15SPaul Saab 193a5f0fb15SPaul Saab /* 194a5f0fb15SPaul Saab * Process any signals we have received. 195a5f0fb15SPaul Saab * A received signal cause a bit to be set in "sigs". 196a5f0fb15SPaul Saab */ 197a5f0fb15SPaul Saab public void 198a5f0fb15SPaul Saab psignals() 199a5f0fb15SPaul Saab { 200a5f0fb15SPaul Saab register int tsignals; 201a5f0fb15SPaul Saab 202a5f0fb15SPaul Saab if ((tsignals = sigs) == 0) 203a5f0fb15SPaul Saab return; 204a5f0fb15SPaul Saab sigs = 0; 205a5f0fb15SPaul Saab 206a5f0fb15SPaul Saab #ifdef SIGTSTP 207a5f0fb15SPaul Saab if (tsignals & S_STOP) 208a5f0fb15SPaul Saab { 209a5f0fb15SPaul Saab /* 210a5f0fb15SPaul Saab * Clean up the terminal. 211a5f0fb15SPaul Saab */ 212a5f0fb15SPaul Saab #ifdef SIGTTOU 213a5f0fb15SPaul Saab LSIGNAL(SIGTTOU, SIG_IGN); 214a5f0fb15SPaul Saab #endif 215a5f0fb15SPaul Saab clear_bot(); 216a5f0fb15SPaul Saab deinit(); 217a5f0fb15SPaul Saab flush(); 218a5f0fb15SPaul Saab raw_mode(0); 219a5f0fb15SPaul Saab #ifdef SIGTTOU 220a5f0fb15SPaul Saab LSIGNAL(SIGTTOU, SIG_DFL); 221a5f0fb15SPaul Saab #endif 222a5f0fb15SPaul Saab LSIGNAL(SIGTSTP, SIG_DFL); 223a5f0fb15SPaul Saab kill(getpid(), SIGTSTP); 224a5f0fb15SPaul Saab /* 225a5f0fb15SPaul Saab * ... Bye bye. ... 226a5f0fb15SPaul Saab * Hopefully we'll be back later and resume here... 227a5f0fb15SPaul Saab * Reset the terminal and arrange to repaint the 228a5f0fb15SPaul Saab * screen when we get back to the main command loop. 229a5f0fb15SPaul Saab */ 230a5f0fb15SPaul Saab LSIGNAL(SIGTSTP, stop); 231a5f0fb15SPaul Saab raw_mode(1); 232a5f0fb15SPaul Saab init(); 233a5f0fb15SPaul Saab screen_trashed = 1; 234a5f0fb15SPaul Saab tsignals |= S_WINCH; 235a5f0fb15SPaul Saab } 236a5f0fb15SPaul Saab #endif 237a5f0fb15SPaul Saab #ifdef S_WINCH 238a5f0fb15SPaul Saab if (tsignals & S_WINCH) 239a5f0fb15SPaul Saab { 240a5f0fb15SPaul Saab int old_width, old_height; 241a5f0fb15SPaul Saab /* 242a5f0fb15SPaul Saab * Re-execute scrsize() to read the new window size. 243a5f0fb15SPaul Saab */ 244a5f0fb15SPaul Saab old_width = sc_width; 245a5f0fb15SPaul Saab old_height = sc_height; 246a5f0fb15SPaul Saab get_term(); 247a5f0fb15SPaul Saab if (sc_width != old_width || sc_height != old_height) 248a5f0fb15SPaul Saab { 249a5f0fb15SPaul Saab wscroll = (sc_height + 1) / 2; 250720c436cSXin LI calc_jump_sline(); 251a5f0fb15SPaul Saab screen_trashed = 1; 252a5f0fb15SPaul Saab } 253a5f0fb15SPaul Saab } 254a5f0fb15SPaul Saab #endif 255a5f0fb15SPaul Saab if (tsignals & S_INTERRUPT) 256a5f0fb15SPaul Saab { 25789dd99dcSXin LI if (quit_on_intr) 25889dd99dcSXin LI quit(QUIT_OK); 259a5f0fb15SPaul Saab } 260a5f0fb15SPaul Saab } 261