1 /* $NetBSD: signal.c,v 1.3 1998/02/04 11:09:12 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1988 Mark Nudleman 5 * Copyright (c) 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 #include <sys/cdefs.h> 38 #ifndef lint 39 #if 0 40 static char sccsid[] = "@(#)signal.c 8.1 (Berkeley) 6/6/93"; 41 #else 42 __RCSID("$NetBSD: signal.c,v 1.3 1998/02/04 11:09:12 christos Exp $"); 43 #endif 44 #endif /* not lint */ 45 46 /* 47 * Routines dealing with signals. 48 * 49 * A signal usually merely causes a bit to be set in the "signals" word. 50 * At some convenient time, the mainline code checks to see if any 51 * signals need processing by calling psignal(). 52 * If we happen to be reading from a file [in iread()] at the time 53 * the signal is received, we call intread to interrupt the iread. 54 */ 55 56 #include <signal.h> 57 #include <unistd.h> 58 59 #include "less.h" 60 #include "extern.h" 61 62 /* 63 * "sigs" contains bits indicating signals which need to be processed. 64 */ 65 int sigs; 66 67 #ifdef SIGTSTP 68 #define S_STOP 02 69 #endif 70 #if defined(SIGWINCH) || defined(SIGWIND) 71 #define S_WINCH 04 72 #endif 73 74 75 static void purgeandquit __P((int)); 76 77 #ifdef SIGTSTP 78 static void stop __P((int)); 79 /* 80 * "Stop" (^Z) signal handler. 81 */ 82 static void 83 stop(n) 84 int n; 85 { 86 (void)signal(SIGTSTP, stop); 87 sigs |= S_STOP; 88 if (reading) 89 intread(); 90 } 91 #endif 92 93 #ifdef SIGWINCH 94 /* 95 * "Window" change handler 96 */ 97 void 98 winch(n) 99 int n; 100 { 101 (void)signal(SIGWINCH, winch); 102 sigs |= S_WINCH; 103 if (reading) 104 intread(); 105 } 106 #else 107 #ifdef SIGWIND 108 /* 109 * "Window" change handler 110 */ 111 winch() 112 { 113 (void)signal(SIGWIND, winch); 114 sigs |= S_WINCH; 115 if (reading) 116 intread(); 117 } 118 #endif 119 #endif 120 121 static void 122 purgeandquit(n) 123 int n; 124 { 125 126 purge(); /* purge buffered output */ 127 quit(); 128 } 129 130 /* 131 * Set up the signal handlers. 132 */ 133 void 134 init_signals(on) 135 int on; 136 { 137 if (on) 138 { 139 /* 140 * Set signal handlers. 141 */ 142 (void)signal(SIGINT, purgeandquit); 143 #ifdef SIGTSTP 144 (void)signal(SIGTSTP, stop); 145 #endif 146 #ifdef SIGWINCH 147 (void)signal(SIGWINCH, winch); 148 #else 149 #ifdef SIGWIND 150 (void)signal(SIGWIND, winch); 151 #endif 152 #endif 153 } else 154 { 155 /* 156 * Restore signals to defaults. 157 */ 158 (void)signal(SIGINT, SIG_DFL); 159 #ifdef SIGTSTP 160 (void)signal(SIGTSTP, SIG_DFL); 161 #endif 162 #ifdef SIGWINCH 163 (void)signal(SIGWINCH, SIG_IGN); 164 #endif 165 #ifdef SIGWIND 166 (void)signal(SIGWIND, SIG_IGN); 167 #endif 168 } 169 } 170 171 /* 172 * Process any signals we have received. 173 * A received signal cause a bit to be set in "sigs". 174 */ 175 void 176 psignals() 177 { 178 int tsignals; 179 180 if ((tsignals = sigs) == 0) 181 return; 182 sigs = 0; 183 184 #ifdef S_WINCH 185 if (tsignals & S_WINCH) 186 { 187 int old_width, old_height; 188 /* 189 * Re-execute get_term() to read the new window size. 190 */ 191 old_width = sc_width; 192 old_height = sc_height; 193 get_term(); 194 if (sc_width != old_width || sc_height != old_height) 195 { 196 scroll = (sc_height + 1) / 2; 197 screen_trashed = 1; 198 } 199 } 200 #endif 201 #ifdef SIGTSTP 202 if (tsignals & S_STOP) 203 { 204 /* 205 * Clean up the terminal. 206 */ 207 #ifdef SIGTTOU 208 (void)signal(SIGTTOU, SIG_IGN); 209 #endif 210 lower_left(); 211 clear_eol(); 212 deinit(); 213 (void)flush(); 214 raw_mode(0); 215 #ifdef SIGTTOU 216 (void)signal(SIGTTOU, SIG_DFL); 217 #endif 218 (void)signal(SIGTSTP, SIG_DFL); 219 (void)kill(getpid(), SIGTSTP); 220 /* 221 * ... Bye bye. ... 222 * Hopefully we'll be back later and resume here... 223 * Reset the terminal and arrange to repaint the 224 * screen when we get back to the main command loop. 225 */ 226 (void)signal(SIGTSTP, stop); 227 raw_mode(1); 228 init(); 229 screen_trashed = 1; 230 } 231 #endif 232 } 233