1 /* $OpenBSD: sig.c,v 1.10 2003/10/31 08:42:24 otto Exp $ */ 2 /* $NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $ */ 3 4 /*- 5 * Copyright (c) 1992, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Christos Zoulas of Cornell University. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "config.h" 37 #if !defined(lint) && !defined(SCCSID) 38 #if 0 39 static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93"; 40 #else 41 static const char rcsid[] = "$OpenBSD: sig.c,v 1.10 2003/10/31 08:42:24 otto Exp $"; 42 #endif 43 #endif /* not lint && not SCCSID */ 44 45 /* 46 * sig.c: Signal handling stuff. 47 * our policy is to trap all signals, set a good state 48 * and pass the ball to our caller. 49 */ 50 #include "el.h" 51 #include <stdlib.h> 52 53 private EditLine *sel = NULL; 54 55 private const int sighdl[] = { 56 #define _DO(a) (a), 57 ALLSIGS 58 #undef _DO 59 - 1 60 }; 61 62 private void sig_handler(int); 63 64 /* sig_handler(): 65 * This is the handler called for all signals 66 * XXX: we cannot pass any data so we just store the old editline 67 * state in a private variable 68 */ 69 private void 70 sig_handler(int signo) 71 { 72 int i; 73 sigset_t nset, oset; 74 75 (void) sigemptyset(&nset); 76 (void) sigaddset(&nset, signo); 77 (void) sigprocmask(SIG_BLOCK, &nset, &oset); 78 79 switch (signo) { 80 case SIGCONT: 81 tty_rawmode(sel); 82 if (ed_redisplay(sel, 0) == CC_REFRESH) 83 re_refresh(sel); 84 term__flush(); 85 break; 86 87 case SIGWINCH: 88 el_resize(sel); 89 break; 90 91 default: 92 tty_cookedmode(sel); 93 break; 94 } 95 96 for (i = 0; sighdl[i] != -1; i++) 97 if (signo == sighdl[i]) 98 break; 99 100 (void) signal(signo, sel->el_signal[i]); 101 (void) sigprocmask(SIG_SETMASK, &oset, NULL); 102 (void) kill(0, signo); 103 } 104 105 106 /* sig_init(): 107 * Initialize all signal stuff 108 */ 109 protected int 110 sig_init(EditLine *el) 111 { 112 int i; 113 sigset_t nset, oset; 114 115 (void) sigemptyset(&nset); 116 #define _DO(a) (void) sigaddset(&nset, a); 117 ALLSIGS 118 #undef _DO 119 (void) sigprocmask(SIG_BLOCK, &nset, &oset); 120 121 #define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(el_signalhandler_t)) 122 123 el->el_signal = (el_signalhandler_t *) el_malloc(SIGSIZE); 124 if (el->el_signal == NULL) 125 return (-1); 126 for (i = 0; sighdl[i] != -1; i++) 127 el->el_signal[i] = SIG_ERR; 128 129 (void) sigprocmask(SIG_SETMASK, &oset, NULL); 130 131 return (0); 132 } 133 134 135 /* sig_end(): 136 * Clear all signal stuff 137 */ 138 protected void 139 sig_end(EditLine *el) 140 { 141 142 el_free((ptr_t) el->el_signal); 143 el->el_signal = NULL; 144 } 145 146 147 /* sig_set(): 148 * set all the signal handlers 149 */ 150 protected void 151 sig_set(EditLine *el) 152 { 153 int i; 154 sigset_t nset, oset; 155 156 (void) sigemptyset(&nset); 157 #define _DO(a) (void) sigaddset(&nset, a); 158 ALLSIGS 159 #undef _DO 160 (void) sigprocmask(SIG_BLOCK, &nset, &oset); 161 162 for (i = 0; sighdl[i] != -1; i++) { 163 el_signalhandler_t s; 164 /* This could happen if we get interrupted */ 165 if ((s = signal(sighdl[i], sig_handler)) != sig_handler) 166 el->el_signal[i] = s; 167 } 168 sel = el; 169 (void) sigprocmask(SIG_SETMASK, &oset, NULL); 170 } 171 172 173 /* sig_clr(): 174 * clear all the signal handlers 175 */ 176 protected void 177 sig_clr(EditLine *el) 178 { 179 int i; 180 sigset_t nset, oset; 181 182 (void) sigemptyset(&nset); 183 #define _DO(a) (void) sigaddset(&nset, a); 184 ALLSIGS 185 #undef _DO 186 (void) sigprocmask(SIG_BLOCK, &nset, &oset); 187 188 for (i = 0; sighdl[i] != -1; i++) 189 if (el->el_signal[i] != SIG_ERR) 190 (void) signal(sighdl[i], el->el_signal[i]); 191 192 sel = NULL; /* we are going to die if the handler is 193 * called */ 194 (void) sigprocmask(SIG_SETMASK, &oset, NULL); 195 } 196