1 /* 2 * Copyright (c) 1988 Mark Nudleman 3 * Copyright (c) 1988 Regents of the University of California. 4 * All rights reserved. 5 * 6 * %sccs.include.redist.c% 7 */ 8 9 #ifndef lint 10 static char sccsid[] = "@(#)signal.c 5.7 (Berkeley) 06/01/90"; 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 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 winch() 64 { 65 (void)signal(SIGWINCH, winch); 66 sigs |= S_WINCH; 67 if (reading) 68 intread(); 69 } 70 #else 71 #ifdef SIGWIND 72 /* 73 * "Window" change handler 74 */ 75 winch() 76 { 77 (void)signal(SIGWIND, winch); 78 sigs |= S_WINCH; 79 if (reading) 80 intread(); 81 } 82 #endif 83 #endif 84 85 static int 86 purgeandquit() 87 { 88 89 purge(); /* purge buffered output */ 90 quit(); 91 } 92 93 /* 94 * Set up the signal handlers. 95 */ 96 init_signals(on) 97 int on; 98 { 99 int quit(); 100 101 if (on) 102 { 103 /* 104 * Set signal handlers. 105 */ 106 (void)signal(SIGINT, purgeandquit); 107 #ifdef SIGTSTP 108 (void)signal(SIGTSTP, stop); 109 #endif 110 #ifdef SIGWINCH 111 (void)signal(SIGWINCH, winch); 112 #else 113 #ifdef SIGWIND 114 (void)signal(SIGWIND, winch); 115 #endif 116 #endif 117 } else 118 { 119 /* 120 * Restore signals to defaults. 121 */ 122 (void)signal(SIGINT, SIG_DFL); 123 #ifdef SIGTSTP 124 (void)signal(SIGTSTP, SIG_DFL); 125 #endif 126 #ifdef SIGWINCH 127 (void)signal(SIGWINCH, SIG_IGN); 128 #endif 129 #ifdef SIGWIND 130 (void)signal(SIGWIND, SIG_IGN); 131 #endif 132 } 133 } 134 135 /* 136 * Process any signals we have received. 137 * A received signal cause a bit to be set in "sigs". 138 */ 139 psignals() 140 { 141 register int tsignals; 142 143 if ((tsignals = sigs) == 0) 144 return; 145 sigs = 0; 146 147 #ifdef S_WINCH 148 if (tsignals & S_WINCH) 149 { 150 int old_width, old_height; 151 /* 152 * Re-execute get_term() to read the new window size. 153 */ 154 old_width = sc_width; 155 old_height = sc_height; 156 get_term(); 157 if (sc_width != old_width || sc_height != old_height) 158 { 159 scroll = (sc_height + 1) / 2; 160 screen_trashed = 1; 161 } 162 } 163 #endif 164 #ifdef SIGTSTP 165 if (tsignals & S_STOP) 166 { 167 /* 168 * Clean up the terminal. 169 */ 170 #ifdef SIGTTOU 171 (void)signal(SIGTTOU, SIG_IGN); 172 #endif 173 lower_left(); 174 clear_eol(); 175 deinit(); 176 (void)flush(); 177 raw_mode(0); 178 #ifdef SIGTTOU 179 (void)signal(SIGTTOU, SIG_DFL); 180 #endif 181 (void)signal(SIGTSTP, SIG_DFL); 182 (void)kill(getpid(), SIGTSTP); 183 /* 184 * ... Bye bye. ... 185 * Hopefully we'll be back later and resume here... 186 * Reset the terminal and arrange to repaint the 187 * screen when we get back to the main command loop. 188 */ 189 (void)signal(SIGTSTP, stop); 190 raw_mode(1); 191 init(); 192 screen_trashed = 1; 193 } 194 #endif 195 } 196