1 /* 2 * Copyright (c) 1988 Mark Nudleman 3 * Copyright (c) 1988, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * %sccs.include.redist.c% 7 */ 8 9 #ifndef lint 10 static char sccsid[] = "@(#)signal.c 8.1 (Berkeley) 06/06/93"; 11 #endif /* not lint */ 12 13 /* 14 * Routines dealing with signals. 15 * 16 * A signal usually merely causes a bit to be set in the "signals" word. 17 * At some convenient time, the mainline code checks to see if any 18 * signals need processing by calling psignal(). 19 * If we happen to be reading from a file [in iread()] at the time 20 * the signal is received, we call intread to interrupt the iread. 21 */ 22 23 #include <less.h> 24 #include <signal.h> 25 26 /* 27 * "sigs" contains bits indicating signals which need to be processed. 28 */ 29 int sigs; 30 31 #ifdef SIGTSTP 32 #define S_STOP 02 33 #endif 34 #if defined(SIGWINCH) || defined(SIGWIND) 35 #define S_WINCH 04 36 #endif 37 38 extern int sc_width, sc_height; 39 extern int screen_trashed; 40 extern int lnloop; 41 extern int linenums; 42 extern int scroll; 43 extern int reading; 44 45 #ifdef SIGTSTP 46 /* 47 * "Stop" (^Z) signal handler. 48 */ 49 static void 50 stop() 51 { 52 (void)signal(SIGTSTP, stop); 53 sigs |= S_STOP; 54 if (reading) 55 intread(); 56 } 57 #endif 58 59 #ifdef SIGWINCH 60 /* 61 * "Window" change handler 62 */ 63 void 64 winch() 65 { 66 (void)signal(SIGWINCH, winch); 67 sigs |= S_WINCH; 68 if (reading) 69 intread(); 70 } 71 #else 72 #ifdef SIGWIND 73 /* 74 * "Window" change handler 75 */ 76 winch() 77 { 78 (void)signal(SIGWIND, winch); 79 sigs |= S_WINCH; 80 if (reading) 81 intread(); 82 } 83 #endif 84 #endif 85 86 static void 87 purgeandquit() 88 { 89 90 purge(); /* purge buffered output */ 91 quit(); 92 } 93 94 /* 95 * Set up the signal handlers. 96 */ 97 init_signals(on) 98 int on; 99 { 100 if (on) 101 { 102 /* 103 * Set signal handlers. 104 */ 105 (void)signal(SIGINT, purgeandquit); 106 #ifdef SIGTSTP 107 (void)signal(SIGTSTP, stop); 108 #endif 109 #ifdef SIGWINCH 110 (void)signal(SIGWINCH, winch); 111 #else 112 #ifdef SIGWIND 113 (void)signal(SIGWIND, winch); 114 #endif 115 #endif 116 } else 117 { 118 /* 119 * Restore signals to defaults. 120 */ 121 (void)signal(SIGINT, SIG_DFL); 122 #ifdef SIGTSTP 123 (void)signal(SIGTSTP, SIG_DFL); 124 #endif 125 #ifdef SIGWINCH 126 (void)signal(SIGWINCH, SIG_IGN); 127 #endif 128 #ifdef SIGWIND 129 (void)signal(SIGWIND, SIG_IGN); 130 #endif 131 } 132 } 133 134 /* 135 * Process any signals we have received. 136 * A received signal cause a bit to be set in "sigs". 137 */ 138 psignals() 139 { 140 register int tsignals; 141 142 if ((tsignals = sigs) == 0) 143 return; 144 sigs = 0; 145 146 #ifdef S_WINCH 147 if (tsignals & S_WINCH) 148 { 149 int old_width, old_height; 150 /* 151 * Re-execute get_term() to read the new window size. 152 */ 153 old_width = sc_width; 154 old_height = sc_height; 155 get_term(); 156 if (sc_width != old_width || sc_height != old_height) 157 { 158 scroll = (sc_height + 1) / 2; 159 screen_trashed = 1; 160 } 161 } 162 #endif 163 #ifdef SIGTSTP 164 if (tsignals & S_STOP) 165 { 166 /* 167 * Clean up the terminal. 168 */ 169 #ifdef SIGTTOU 170 (void)signal(SIGTTOU, SIG_IGN); 171 #endif 172 lower_left(); 173 clear_eol(); 174 deinit(); 175 (void)flush(); 176 raw_mode(0); 177 #ifdef SIGTTOU 178 (void)signal(SIGTTOU, SIG_DFL); 179 #endif 180 (void)signal(SIGTSTP, SIG_DFL); 181 (void)kill(getpid(), SIGTSTP); 182 /* 183 * ... Bye bye. ... 184 * Hopefully we'll be back later and resume here... 185 * Reset the terminal and arrange to repaint the 186 * screen when we get back to the main command loop. 187 */ 188 (void)signal(SIGTSTP, stop); 189 raw_mode(1); 190 init(); 191 screen_trashed = 1; 192 } 193 #endif 194 } 195