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