1a5f0fb15SPaul Saab /* 2*c77c4889SXin LI * Copyright (C) 1984-2024 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 * 796e55cc7SXin LI * For more information, see the README file. 8a5f0fb15SPaul Saab */ 9a5f0fb15SPaul Saab 1051525cb0SPaul Saab /* $FreeBSD$ */ 11a5f0fb15SPaul Saab 12a5f0fb15SPaul Saab /* 13a5f0fb15SPaul Saab * Routines dealing with signals. 14a5f0fb15SPaul Saab * 15a5f0fb15SPaul Saab * A signal usually merely causes a bit to be set in the "signals" word. 16a5f0fb15SPaul Saab * At some convenient time, the mainline code checks to see if any 17a5f0fb15SPaul Saab * signals need processing by calling psignal(). 18a5f0fb15SPaul Saab * If we happen to be reading from a file [in iread()] at the time 19a5f0fb15SPaul Saab * the signal is received, we call intread to interrupt the iread. 20a5f0fb15SPaul Saab */ 21a5f0fb15SPaul Saab 22a5f0fb15SPaul Saab #include "less.h" 23a5f0fb15SPaul Saab #include <signal.h> 24a5f0fb15SPaul Saab 25a5f0fb15SPaul Saab /* 26a5f0fb15SPaul Saab * "sigs" contains bits indicating signals which need to be processed. 27a5f0fb15SPaul Saab */ 28a5f0fb15SPaul Saab public int sigs; 29a5f0fb15SPaul Saab 30a5f0fb15SPaul Saab extern int sc_width, sc_height; 31a5f0fb15SPaul Saab extern int linenums; 32a5f0fb15SPaul Saab extern int wscroll; 33a5f0fb15SPaul Saab extern int reading; 3489dd99dcSXin LI extern int quit_on_intr; 35720c436cSXin LI extern long jump_sline_fraction; 36a5f0fb15SPaul Saab 372235c7feSXin LI extern int less_is_more; 382235c7feSXin LI 39a5f0fb15SPaul Saab /* 40a5f0fb15SPaul Saab * Interrupt signal handler. 41a5f0fb15SPaul Saab */ 42b7780dbeSXin LI #if MSDOS_COMPILER!=WIN32C 43a5f0fb15SPaul Saab /* ARGSUSED*/ 44d713e089SXin LI static RETSIGTYPE u_interrupt(int type) 45a5f0fb15SPaul Saab { 46*c77c4889SXin LI (void) type; 477374caaaSXin LI bell(); 48a5f0fb15SPaul Saab #if OS2 49a5f0fb15SPaul Saab LSIGNAL(SIGINT, SIG_ACK); 50a5f0fb15SPaul Saab #endif 51a5f0fb15SPaul Saab LSIGNAL(SIGINT, u_interrupt); 52a5f0fb15SPaul Saab sigs |= S_INTERRUPT; 53a5f0fb15SPaul Saab #if MSDOS_COMPILER==DJGPPC 54a5f0fb15SPaul Saab /* 55a5f0fb15SPaul Saab * If a keyboard has been hit, it must be Ctrl-C 56a5f0fb15SPaul Saab * (as opposed to Ctrl-Break), so consume it. 57a5f0fb15SPaul Saab * (Otherwise, Less will beep when it sees Ctrl-C from keyboard.) 58a5f0fb15SPaul Saab */ 59a5f0fb15SPaul Saab if (kbhit()) 60a5f0fb15SPaul Saab getkey(); 61a5f0fb15SPaul Saab #endif 62720c436cSXin LI if (less_is_more) 6351525cb0SPaul Saab quit(0); 642235c7feSXin LI #if HILITE_SEARCH 652235c7feSXin LI set_filter_pattern(NULL, 0); 662235c7feSXin LI #endif 67a5f0fb15SPaul Saab if (reading) 687374caaaSXin LI intread(); /* May longjmp */ 69a5f0fb15SPaul Saab } 70b7780dbeSXin LI #endif 71a5f0fb15SPaul Saab 72a5f0fb15SPaul Saab #ifdef SIGTSTP 73a5f0fb15SPaul Saab /* 74a5f0fb15SPaul Saab * "Stop" (^Z) signal handler. 75a5f0fb15SPaul Saab */ 76a5f0fb15SPaul Saab /* ARGSUSED*/ 77d713e089SXin LI static RETSIGTYPE stop(int type) 78a5f0fb15SPaul Saab { 79*c77c4889SXin LI (void) type; 80a5f0fb15SPaul Saab LSIGNAL(SIGTSTP, stop); 81a5f0fb15SPaul Saab sigs |= S_STOP; 82a5f0fb15SPaul Saab if (reading) 83a5f0fb15SPaul Saab intread(); 84a5f0fb15SPaul Saab } 85a5f0fb15SPaul Saab #endif 86a5f0fb15SPaul Saab 87b2ea2440SXin LI #undef SIG_LESSWINDOW 88a5f0fb15SPaul Saab #ifdef SIGWINCH 89b2ea2440SXin LI #define SIG_LESSWINDOW SIGWINCH 90a5f0fb15SPaul Saab #else 91a5f0fb15SPaul Saab #ifdef SIGWIND 92b2ea2440SXin LI #define SIG_LESSWINDOW SIGWIND 93b2ea2440SXin LI #endif 94b2ea2440SXin LI #endif 95b2ea2440SXin LI 96b2ea2440SXin LI #ifdef SIG_LESSWINDOW 97a5f0fb15SPaul Saab /* 98a5f0fb15SPaul Saab * "Window" change handler 99a5f0fb15SPaul Saab */ 100a5f0fb15SPaul Saab /* ARGSUSED*/ 101d713e089SXin LI public RETSIGTYPE winch(int type) 102a5f0fb15SPaul Saab { 103*c77c4889SXin LI (void) type; 104b2ea2440SXin LI LSIGNAL(SIG_LESSWINDOW, winch); 105a5f0fb15SPaul Saab sigs |= S_WINCH; 106a5f0fb15SPaul Saab if (reading) 107a5f0fb15SPaul Saab intread(); 108a5f0fb15SPaul Saab } 109a5f0fb15SPaul Saab #endif 110a5f0fb15SPaul Saab 111a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 112a5f0fb15SPaul Saab /* 113a5f0fb15SPaul Saab * Handle CTRL-C and CTRL-BREAK keys. 114a5f0fb15SPaul Saab */ 115b7780dbeSXin LI #define WIN32_LEAN_AND_MEAN 116b7780dbeSXin LI #include <windows.h> 117a5f0fb15SPaul Saab 118d713e089SXin LI static BOOL WINAPI wbreak_handler(DWORD dwCtrlType) 119a5f0fb15SPaul Saab { 120a5f0fb15SPaul Saab switch (dwCtrlType) 121a5f0fb15SPaul Saab { 122a5f0fb15SPaul Saab case CTRL_C_EVENT: 123a5f0fb15SPaul Saab case CTRL_BREAK_EVENT: 124a5f0fb15SPaul Saab sigs |= S_INTERRUPT; 1252235c7feSXin LI #if HILITE_SEARCH 1262235c7feSXin LI set_filter_pattern(NULL, 0); 1272235c7feSXin LI #endif 128a5f0fb15SPaul Saab return (TRUE); 129a5f0fb15SPaul Saab default: 130a5f0fb15SPaul Saab break; 131a5f0fb15SPaul Saab } 132a5f0fb15SPaul Saab return (FALSE); 133a5f0fb15SPaul Saab } 134a5f0fb15SPaul Saab #endif 135a5f0fb15SPaul Saab 136d713e089SXin LI static RETSIGTYPE terminate(int type) 137b2ea2440SXin LI { 138*c77c4889SXin LI (void) type; 139b2ea2440SXin LI quit(15); 140b2ea2440SXin LI } 141b2ea2440SXin LI 142a5f0fb15SPaul Saab /* 143a5f0fb15SPaul Saab * Set up the signal handlers. 144a5f0fb15SPaul Saab */ 145d713e089SXin LI public void init_signals(int on) 146a5f0fb15SPaul Saab { 147a5f0fb15SPaul Saab if (on) 148a5f0fb15SPaul Saab { 149a5f0fb15SPaul Saab /* 150a5f0fb15SPaul Saab * Set signal handlers. 151a5f0fb15SPaul Saab */ 152a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 153a5f0fb15SPaul Saab SetConsoleCtrlHandler(wbreak_handler, TRUE); 154b7780dbeSXin LI #else 155b7780dbeSXin LI (void) LSIGNAL(SIGINT, u_interrupt); 156a5f0fb15SPaul Saab #endif 157a5f0fb15SPaul Saab #ifdef SIGTSTP 158*c77c4889SXin LI (void) LSIGNAL(SIGTSTP, !secure_allow(SF_STOP) ? SIG_IGN : 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 169b2ea2440SXin LI #ifdef SIGTERM 170b2ea2440SXin LI (void) LSIGNAL(SIGTERM, terminate); 171b2ea2440SXin LI #endif 172a5f0fb15SPaul Saab } else 173a5f0fb15SPaul Saab { 174a5f0fb15SPaul Saab /* 175a5f0fb15SPaul Saab * Restore signals to defaults. 176a5f0fb15SPaul Saab */ 177a5f0fb15SPaul Saab #if MSDOS_COMPILER==WIN32C 178a5f0fb15SPaul Saab SetConsoleCtrlHandler(wbreak_handler, FALSE); 179b7780dbeSXin LI #else 180b7780dbeSXin LI (void) LSIGNAL(SIGINT, SIG_DFL); 181a5f0fb15SPaul Saab #endif 182a5f0fb15SPaul Saab #ifdef SIGTSTP 183a5f0fb15SPaul Saab (void) LSIGNAL(SIGTSTP, SIG_DFL); 184a5f0fb15SPaul Saab #endif 185a5f0fb15SPaul Saab #ifdef SIGWINCH 186a5f0fb15SPaul Saab (void) LSIGNAL(SIGWINCH, SIG_IGN); 187a5f0fb15SPaul Saab #endif 188a5f0fb15SPaul Saab #ifdef SIGWIND 189a5f0fb15SPaul Saab (void) LSIGNAL(SIGWIND, SIG_IGN); 190a5f0fb15SPaul Saab #endif 191a5f0fb15SPaul Saab #ifdef SIGQUIT 192a5f0fb15SPaul Saab (void) LSIGNAL(SIGQUIT, SIG_DFL); 193a5f0fb15SPaul Saab #endif 194b2ea2440SXin LI #ifdef SIGTERM 195b2ea2440SXin LI (void) LSIGNAL(SIGTERM, SIG_DFL); 196b2ea2440SXin LI #endif 197a5f0fb15SPaul Saab } 198a5f0fb15SPaul Saab } 199a5f0fb15SPaul Saab 200a5f0fb15SPaul Saab /* 201a5f0fb15SPaul Saab * Process any signals we have received. 202a5f0fb15SPaul Saab * A received signal cause a bit to be set in "sigs". 203a5f0fb15SPaul Saab */ 204d713e089SXin LI public void psignals(void) 205a5f0fb15SPaul Saab { 2061ea31627SRobert Watson int tsignals; 207a5f0fb15SPaul Saab 208a5f0fb15SPaul Saab if ((tsignals = sigs) == 0) 209a5f0fb15SPaul Saab return; 210a5f0fb15SPaul Saab sigs = 0; 211a5f0fb15SPaul Saab 212a5f0fb15SPaul Saab #ifdef SIGTSTP 213a5f0fb15SPaul Saab if (tsignals & S_STOP) 214a5f0fb15SPaul Saab { 215a5f0fb15SPaul Saab /* 216a5f0fb15SPaul Saab * Clean up the terminal. 217a5f0fb15SPaul Saab */ 218a5f0fb15SPaul Saab #ifdef SIGTTOU 219a5f0fb15SPaul Saab LSIGNAL(SIGTTOU, SIG_IGN); 220a5f0fb15SPaul Saab #endif 221a5f0fb15SPaul Saab clear_bot(); 222a5f0fb15SPaul Saab deinit(); 223a5f0fb15SPaul Saab flush(); 224a5f0fb15SPaul Saab raw_mode(0); 225a5f0fb15SPaul Saab #ifdef SIGTTOU 226a5f0fb15SPaul Saab LSIGNAL(SIGTTOU, SIG_DFL); 227a5f0fb15SPaul Saab #endif 228a5f0fb15SPaul Saab LSIGNAL(SIGTSTP, SIG_DFL); 229a5f0fb15SPaul Saab kill(getpid(), SIGTSTP); 230a5f0fb15SPaul Saab /* 231a5f0fb15SPaul Saab * ... Bye bye. ... 232a5f0fb15SPaul Saab * Hopefully we'll be back later and resume here... 233a5f0fb15SPaul Saab * Reset the terminal and arrange to repaint the 234a5f0fb15SPaul Saab * screen when we get back to the main command loop. 235a5f0fb15SPaul Saab */ 236a5f0fb15SPaul Saab LSIGNAL(SIGTSTP, stop); 237a5f0fb15SPaul Saab raw_mode(1); 238a5f0fb15SPaul Saab init(); 239*c77c4889SXin LI screen_trashed(); 240a5f0fb15SPaul Saab tsignals |= S_WINCH; 241a5f0fb15SPaul Saab } 242a5f0fb15SPaul Saab #endif 243a5f0fb15SPaul Saab #ifdef S_WINCH 244a5f0fb15SPaul Saab if (tsignals & S_WINCH) 245a5f0fb15SPaul Saab { 246a5f0fb15SPaul Saab int old_width, old_height; 247a5f0fb15SPaul Saab /* 248a5f0fb15SPaul Saab * Re-execute scrsize() to read the new window size. 249a5f0fb15SPaul Saab */ 250a5f0fb15SPaul Saab old_width = sc_width; 251a5f0fb15SPaul Saab old_height = sc_height; 252a5f0fb15SPaul Saab get_term(); 253a5f0fb15SPaul Saab if (sc_width != old_width || sc_height != old_height) 254a5f0fb15SPaul Saab { 255a5f0fb15SPaul Saab wscroll = (sc_height + 1) / 2; 256*c77c4889SXin LI screen_size_changed(); 257a5f0fb15SPaul Saab } 258*c77c4889SXin LI screen_trashed(); 259a5f0fb15SPaul Saab } 260a5f0fb15SPaul Saab #endif 261a5f0fb15SPaul Saab if (tsignals & S_INTERRUPT) 262a5f0fb15SPaul Saab { 26389dd99dcSXin LI if (quit_on_intr) 26433096f16SXin LI quit(QUIT_INTERRUPT); 265*c77c4889SXin LI getcc_clear(); 266*c77c4889SXin LI #if MSDOS_COMPILER==WIN32C 267*c77c4889SXin LI win32_getch_clear(); 268*c77c4889SXin LI #endif 269a5f0fb15SPaul Saab } 270a5f0fb15SPaul Saab } 271