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