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