sig.c revision 276881
1276881Sbapt/* $NetBSD: sig.c,v 1.17 2011/07/28 20:50:55 christos Exp $ */ 2276881Sbapt 31573Srgrimes/*- 41573Srgrimes * Copyright (c) 1992, 1993 51573Srgrimes * The Regents of the University of California. All rights reserved. 61573Srgrimes * 71573Srgrimes * This code is derived from software contributed to Berkeley by 81573Srgrimes * Christos Zoulas of Cornell University. 91573Srgrimes * 101573Srgrimes * Redistribution and use in source and binary forms, with or without 111573Srgrimes * modification, are permitted provided that the following conditions 121573Srgrimes * are met: 131573Srgrimes * 1. Redistributions of source code must retain the above copyright 141573Srgrimes * notice, this list of conditions and the following disclaimer. 151573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 161573Srgrimes * notice, this list of conditions and the following disclaimer in the 171573Srgrimes * documentation and/or other materials provided with the distribution. 18148834Sstefanf * 3. Neither the name of the University nor the names of its contributors 191573Srgrimes * may be used to endorse or promote products derived from this software 201573Srgrimes * without specific prior written permission. 211573Srgrimes * 221573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 231573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 241573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 251573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 261573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 271573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 281573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 291573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 301573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 311573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 321573Srgrimes * SUCH DAMAGE. 331573Srgrimes */ 341573Srgrimes 35276881Sbapt#include "config.h" 361573Srgrimes#if !defined(lint) && !defined(SCCSID) 37276881Sbapt#if 0 381573Srgrimesstatic char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93"; 39276881Sbapt#else 40276881Sbapt__RCSID("$NetBSD: sig.c,v 1.17 2011/07/28 20:50:55 christos Exp $"); 41276881Sbapt#endif 421573Srgrimes#endif /* not lint && not SCCSID */ 4384260Sobrien#include <sys/cdefs.h> 4484260Sobrien__FBSDID("$FreeBSD: head/lib/libedit/sig.c 276881 2015-01-09 07:40:56Z bapt $"); 451573Srgrimes 461573Srgrimes/* 471573Srgrimes * sig.c: Signal handling stuff. 481573Srgrimes * our policy is to trap all signals, set a good state 491573Srgrimes * and pass the ball to our caller. 501573Srgrimes */ 511573Srgrimes#include "el.h" 521573Srgrimes#include <stdlib.h> 531573Srgrimes 541573Srgrimesprivate EditLine *sel = NULL; 551573Srgrimes 5684260Sobrienprivate const int sighdl[] = { 5784260Sobrien#define _DO(a) (a), 5884260Sobrien ALLSIGS 5984260Sobrien#undef _DO 6084260Sobrien - 1 611573Srgrimes}; 621573Srgrimes 6384260Sobrienprivate void sig_handler(int); 641573Srgrimes 651573Srgrimes/* sig_handler(): 661573Srgrimes * This is the handler called for all signals 671573Srgrimes * XXX: we cannot pass any data so we just store the old editline 681573Srgrimes * state in a private variable 691573Srgrimes */ 701573Srgrimesprivate void 7184260Sobriensig_handler(int signo) 721573Srgrimes{ 7384260Sobrien int i; 7484260Sobrien sigset_t nset, oset; 751573Srgrimes 7684260Sobrien (void) sigemptyset(&nset); 7784260Sobrien (void) sigaddset(&nset, signo); 7884260Sobrien (void) sigprocmask(SIG_BLOCK, &nset, &oset); 791573Srgrimes 80238378Spfg sel->el_signal->sig_no = signo; 81238378Spfg 8284260Sobrien switch (signo) { 8384260Sobrien case SIGCONT: 8484260Sobrien tty_rawmode(sel); 8584260Sobrien if (ed_redisplay(sel, 0) == CC_REFRESH) 8684260Sobrien re_refresh(sel); 87276881Sbapt terminal__flush(sel); 8884260Sobrien break; 891573Srgrimes 9084260Sobrien case SIGWINCH: 9184260Sobrien el_resize(sel); 9284260Sobrien break; 931573Srgrimes 9484260Sobrien default: 9584260Sobrien tty_cookedmode(sel); 9684260Sobrien break; 9784260Sobrien } 981573Srgrimes 9984260Sobrien for (i = 0; sighdl[i] != -1; i++) 10084260Sobrien if (signo == sighdl[i]) 10184260Sobrien break; 1021573Srgrimes 103237448Spfg (void) sigaction(signo, &sel->el_signal->sig_action[i], NULL); 104237448Spfg sel->el_signal->sig_action[i].sa_handler = SIG_ERR; 105237448Spfg sel->el_signal->sig_action[i].sa_flags = 0; 106237448Spfg sigemptyset(&sel->el_signal->sig_action[i].sa_mask); 10784260Sobrien (void) sigprocmask(SIG_SETMASK, &oset, NULL); 10884260Sobrien (void) kill(0, signo); 1091573Srgrimes} 1101573Srgrimes 1111573Srgrimes 1121573Srgrimes/* sig_init(): 1131573Srgrimes * Initialize all signal stuff 1141573Srgrimes */ 1151573Srgrimesprotected int 11684260Sobriensig_init(EditLine *el) 1171573Srgrimes{ 118237448Spfg size_t i; 119237448Spfg sigset_t *nset, oset; 1201573Srgrimes 121237448Spfg el->el_signal = el_malloc(sizeof(*el->el_signal)); 122237448Spfg if (el->el_signal == NULL) 123237448Spfg return -1; 124237448Spfg 125237448Spfg nset = &el->el_signal->sig_set; 126237448Spfg (void) sigemptyset(nset); 127237448Spfg#define _DO(a) (void) sigaddset(nset, a); 12884260Sobrien ALLSIGS 12984260Sobrien#undef _DO 130237448Spfg (void) sigprocmask(SIG_BLOCK, nset, &oset); 1311573Srgrimes 132237448Spfg for (i = 0; sighdl[i] != -1; i++) { 133237448Spfg el->el_signal->sig_action[i].sa_handler = SIG_ERR; 134237448Spfg el->el_signal->sig_action[i].sa_flags = 0; 135237448Spfg sigemptyset(&el->el_signal->sig_action[i].sa_mask); 136237448Spfg } 1371573Srgrimes 13884260Sobrien (void) sigprocmask(SIG_SETMASK, &oset, NULL); 1391573Srgrimes 140237448Spfg return 0; 1411573Srgrimes} 1421573Srgrimes 1431573Srgrimes 1441573Srgrimes/* sig_end(): 1451573Srgrimes * Clear all signal stuff 1461573Srgrimes */ 1471573Srgrimesprotected void 14884260Sobriensig_end(EditLine *el) 1491573Srgrimes{ 15084260Sobrien 151276881Sbapt el_free(el->el_signal); 15284260Sobrien el->el_signal = NULL; 1531573Srgrimes} 1541573Srgrimes 1551573Srgrimes 1561573Srgrimes/* sig_set(): 1571573Srgrimes * set all the signal handlers 1581573Srgrimes */ 1591573Srgrimesprotected void 16084260Sobriensig_set(EditLine *el) 1611573Srgrimes{ 162237448Spfg size_t i; 163237448Spfg sigset_t oset; 164237448Spfg struct sigaction osa, nsa; 1651573Srgrimes 166237448Spfg nsa.sa_handler = sig_handler; 167238378Spfg nsa.sa_flags = 0; 168237448Spfg sigemptyset(&nsa.sa_mask); 1691573Srgrimes 170237448Spfg (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset); 171237448Spfg 17284260Sobrien for (i = 0; sighdl[i] != -1; i++) { 17384260Sobrien /* This could happen if we get interrupted */ 174237448Spfg if (sigaction(sighdl[i], &nsa, &osa) != -1 && 175237448Spfg osa.sa_handler != sig_handler) 176237448Spfg el->el_signal->sig_action[i] = osa; 17784260Sobrien } 17884260Sobrien sel = el; 17984260Sobrien (void) sigprocmask(SIG_SETMASK, &oset, NULL); 1801573Srgrimes} 1811573Srgrimes 1821573Srgrimes 1831573Srgrimes/* sig_clr(): 1841573Srgrimes * clear all the signal handlers 1851573Srgrimes */ 1861573Srgrimesprotected void 18784260Sobriensig_clr(EditLine *el) 1881573Srgrimes{ 189237448Spfg size_t i; 190237448Spfg sigset_t oset; 1911573Srgrimes 192237448Spfg (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset); 1931573Srgrimes 19484260Sobrien for (i = 0; sighdl[i] != -1; i++) 195237448Spfg if (el->el_signal->sig_action[i].sa_handler != SIG_ERR) 196237448Spfg (void)sigaction(sighdl[i], 197237448Spfg &el->el_signal->sig_action[i], NULL); 1981573Srgrimes 19984260Sobrien sel = NULL; /* we are going to die if the handler is 20084260Sobrien * called */ 201237448Spfg (void)sigprocmask(SIG_SETMASK, &oset, NULL); 2021573Srgrimes} 203