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