11573Srgrimes/*- 21573Srgrimes * Copyright (c) 1992, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * This code is derived from software contributed to Berkeley by 61573Srgrimes * Christos Zoulas of Cornell University. 71573Srgrimes * 81573Srgrimes * Redistribution and use in source and binary forms, with or without 91573Srgrimes * modification, are permitted provided that the following conditions 101573Srgrimes * are met: 111573Srgrimes * 1. Redistributions of source code must retain the above copyright 121573Srgrimes * notice, this list of conditions and the following disclaimer. 131573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141573Srgrimes * notice, this list of conditions and the following disclaimer in the 151573Srgrimes * documentation and/or other materials provided with the distribution. 16148834Sstefanf * 3. Neither the name of the University nor the names of its contributors 171573Srgrimes * may be used to endorse or promote products derived from this software 181573Srgrimes * without specific prior written permission. 191573Srgrimes * 201573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301573Srgrimes * SUCH DAMAGE. 3184260Sobrien * 32238378Spfg * $NetBSD: sig.c,v 1.15 2009/02/19 15:20:22 christos Exp $ 331573Srgrimes */ 341573Srgrimes 351573Srgrimes#if !defined(lint) && !defined(SCCSID) 361573Srgrimesstatic char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93"; 371573Srgrimes#endif /* not lint && not SCCSID */ 3884260Sobrien#include <sys/cdefs.h> 3984260Sobrien__FBSDID("$FreeBSD$"); 401573Srgrimes 411573Srgrimes/* 421573Srgrimes * sig.c: Signal handling stuff. 431573Srgrimes * our policy is to trap all signals, set a good state 441573Srgrimes * and pass the ball to our caller. 451573Srgrimes */ 461573Srgrimes#include "sys.h" 471573Srgrimes#include "el.h" 481573Srgrimes#include <stdlib.h> 491573Srgrimes 501573Srgrimesprivate EditLine *sel = NULL; 511573Srgrimes 5284260Sobrienprivate const int sighdl[] = { 5384260Sobrien#define _DO(a) (a), 5484260Sobrien ALLSIGS 5584260Sobrien#undef _DO 5684260Sobrien - 1 571573Srgrimes}; 581573Srgrimes 5984260Sobrienprivate void sig_handler(int); 601573Srgrimes 611573Srgrimes/* sig_handler(): 621573Srgrimes * This is the handler called for all signals 631573Srgrimes * XXX: we cannot pass any data so we just store the old editline 641573Srgrimes * state in a private variable 651573Srgrimes */ 661573Srgrimesprivate void 6784260Sobriensig_handler(int signo) 681573Srgrimes{ 6984260Sobrien int i; 7084260Sobrien sigset_t nset, oset; 711573Srgrimes 7284260Sobrien (void) sigemptyset(&nset); 7384260Sobrien (void) sigaddset(&nset, signo); 7484260Sobrien (void) sigprocmask(SIG_BLOCK, &nset, &oset); 751573Srgrimes 76238378Spfg sel->el_signal->sig_no = signo; 77238378Spfg 7884260Sobrien switch (signo) { 7984260Sobrien case SIGCONT: 8084260Sobrien tty_rawmode(sel); 8184260Sobrien if (ed_redisplay(sel, 0) == CC_REFRESH) 8284260Sobrien re_refresh(sel); 83237448Spfg term__flush(sel); 8484260Sobrien break; 851573Srgrimes 8684260Sobrien case SIGWINCH: 8784260Sobrien el_resize(sel); 8884260Sobrien break; 891573Srgrimes 9084260Sobrien default: 9184260Sobrien tty_cookedmode(sel); 9284260Sobrien break; 9384260Sobrien } 941573Srgrimes 9584260Sobrien for (i = 0; sighdl[i] != -1; i++) 9684260Sobrien if (signo == sighdl[i]) 9784260Sobrien break; 981573Srgrimes 99237448Spfg (void) sigaction(signo, &sel->el_signal->sig_action[i], NULL); 100237448Spfg sel->el_signal->sig_action[i].sa_handler = SIG_ERR; 101237448Spfg sel->el_signal->sig_action[i].sa_flags = 0; 102237448Spfg sigemptyset(&sel->el_signal->sig_action[i].sa_mask); 10384260Sobrien (void) sigprocmask(SIG_SETMASK, &oset, NULL); 10484260Sobrien (void) kill(0, signo); 1051573Srgrimes} 1061573Srgrimes 1071573Srgrimes 1081573Srgrimes/* sig_init(): 1091573Srgrimes * Initialize all signal stuff 1101573Srgrimes */ 1111573Srgrimesprotected int 11284260Sobriensig_init(EditLine *el) 1131573Srgrimes{ 114237448Spfg size_t i; 115237448Spfg sigset_t *nset, oset; 1161573Srgrimes 117237448Spfg el->el_signal = el_malloc(sizeof(*el->el_signal)); 118237448Spfg if (el->el_signal == NULL) 119237448Spfg return -1; 120237448Spfg 121237448Spfg nset = &el->el_signal->sig_set; 122237448Spfg (void) sigemptyset(nset); 123237448Spfg#define _DO(a) (void) sigaddset(nset, a); 12484260Sobrien ALLSIGS 12584260Sobrien#undef _DO 126237448Spfg (void) sigprocmask(SIG_BLOCK, nset, &oset); 1271573Srgrimes 128237448Spfg for (i = 0; sighdl[i] != -1; i++) { 129237448Spfg el->el_signal->sig_action[i].sa_handler = SIG_ERR; 130237448Spfg el->el_signal->sig_action[i].sa_flags = 0; 131237448Spfg sigemptyset(&el->el_signal->sig_action[i].sa_mask); 132237448Spfg } 1331573Srgrimes 13484260Sobrien (void) sigprocmask(SIG_SETMASK, &oset, NULL); 1351573Srgrimes 136237448Spfg return 0; 1371573Srgrimes} 1381573Srgrimes 1391573Srgrimes 1401573Srgrimes/* sig_end(): 1411573Srgrimes * Clear all signal stuff 1421573Srgrimes */ 1431573Srgrimesprotected void 14484260Sobriensig_end(EditLine *el) 1451573Srgrimes{ 14684260Sobrien 14784260Sobrien el_free((ptr_t) el->el_signal); 14884260Sobrien el->el_signal = NULL; 1491573Srgrimes} 1501573Srgrimes 1511573Srgrimes 1521573Srgrimes/* sig_set(): 1531573Srgrimes * set all the signal handlers 1541573Srgrimes */ 1551573Srgrimesprotected void 15684260Sobriensig_set(EditLine *el) 1571573Srgrimes{ 158237448Spfg size_t i; 159237448Spfg sigset_t oset; 160237448Spfg struct sigaction osa, nsa; 1611573Srgrimes 162237448Spfg nsa.sa_handler = sig_handler; 163238378Spfg nsa.sa_flags = 0; 164237448Spfg sigemptyset(&nsa.sa_mask); 1651573Srgrimes 166237448Spfg (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset); 167237448Spfg 16884260Sobrien for (i = 0; sighdl[i] != -1; i++) { 16984260Sobrien /* This could happen if we get interrupted */ 170237448Spfg if (sigaction(sighdl[i], &nsa, &osa) != -1 && 171237448Spfg osa.sa_handler != sig_handler) 172237448Spfg el->el_signal->sig_action[i] = osa; 17384260Sobrien } 17484260Sobrien sel = el; 17584260Sobrien (void) sigprocmask(SIG_SETMASK, &oset, NULL); 1761573Srgrimes} 1771573Srgrimes 1781573Srgrimes 1791573Srgrimes/* sig_clr(): 1801573Srgrimes * clear all the signal handlers 1811573Srgrimes */ 1821573Srgrimesprotected void 18384260Sobriensig_clr(EditLine *el) 1841573Srgrimes{ 185237448Spfg size_t i; 186237448Spfg sigset_t oset; 1871573Srgrimes 188237448Spfg (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset); 1891573Srgrimes 19084260Sobrien for (i = 0; sighdl[i] != -1; i++) 191237448Spfg if (el->el_signal->sig_action[i].sa_handler != SIG_ERR) 192237448Spfg (void)sigaction(sighdl[i], 193237448Spfg &el->el_signal->sig_action[i], NULL); 1941573Srgrimes 19584260Sobrien sel = NULL; /* we are going to die if the handler is 19684260Sobrien * called */ 197237448Spfg (void)sigprocmask(SIG_SETMASK, &oset, NULL); 1981573Srgrimes} 199