1313981Spfg/* $NetBSD: sig.c,v 1.24 2016/02/16 19:08:41 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 40313981Spfg__RCSID("$NetBSD: sig.c,v 1.24 2016/02/16 19:08:41 christos Exp $"); 41276881Sbapt#endif 421573Srgrimes#endif /* not lint && not SCCSID */ 4384260Sobrien#include <sys/cdefs.h> 4484260Sobrien__FBSDID("$FreeBSD: stable/11/lib/libedit/sig.c 313981 2017-02-20 03:33:59Z pfg $"); 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 */ 51313981Spfg#include <errno.h> 521573Srgrimes#include <stdlib.h> 531573Srgrimes 54313981Spfg#include "el.h" 55313981Spfg#include "common.h" 56313981Spfg 571573Srgrimesprivate EditLine *sel = NULL; 581573Srgrimes 5984260Sobrienprivate const int sighdl[] = { 6084260Sobrien#define _DO(a) (a), 6184260Sobrien ALLSIGS 6284260Sobrien#undef _DO 6384260Sobrien - 1 641573Srgrimes}; 651573Srgrimes 6684260Sobrienprivate void sig_handler(int); 671573Srgrimes 681573Srgrimes/* sig_handler(): 691573Srgrimes * This is the handler called for all signals 701573Srgrimes * XXX: we cannot pass any data so we just store the old editline 711573Srgrimes * state in a private variable 721573Srgrimes */ 731573Srgrimesprivate void 7484260Sobriensig_handler(int signo) 751573Srgrimes{ 76313981Spfg int i, save_errno; 7784260Sobrien sigset_t nset, oset; 781573Srgrimes 79313981Spfg save_errno = errno; 8084260Sobrien (void) sigemptyset(&nset); 8184260Sobrien (void) sigaddset(&nset, signo); 8284260Sobrien (void) sigprocmask(SIG_BLOCK, &nset, &oset); 831573Srgrimes 84238378Spfg sel->el_signal->sig_no = signo; 85238378Spfg 8684260Sobrien switch (signo) { 8784260Sobrien case SIGCONT: 8884260Sobrien tty_rawmode(sel); 8984260Sobrien if (ed_redisplay(sel, 0) == CC_REFRESH) 9084260Sobrien re_refresh(sel); 91276881Sbapt terminal__flush(sel); 9284260Sobrien break; 931573Srgrimes 9484260Sobrien case SIGWINCH: 9584260Sobrien el_resize(sel); 9684260Sobrien break; 971573Srgrimes 9884260Sobrien default: 9984260Sobrien tty_cookedmode(sel); 10084260Sobrien break; 10184260Sobrien } 1021573Srgrimes 10384260Sobrien for (i = 0; sighdl[i] != -1; i++) 10484260Sobrien if (signo == sighdl[i]) 10584260Sobrien break; 1061573Srgrimes 107237448Spfg (void) sigaction(signo, &sel->el_signal->sig_action[i], NULL); 108237448Spfg sel->el_signal->sig_action[i].sa_handler = SIG_ERR; 109237448Spfg sel->el_signal->sig_action[i].sa_flags = 0; 110237448Spfg sigemptyset(&sel->el_signal->sig_action[i].sa_mask); 11184260Sobrien (void) sigprocmask(SIG_SETMASK, &oset, NULL); 11284260Sobrien (void) kill(0, signo); 113313981Spfg errno = save_errno; 1141573Srgrimes} 1151573Srgrimes 1161573Srgrimes 1171573Srgrimes/* sig_init(): 1181573Srgrimes * Initialize all signal stuff 1191573Srgrimes */ 1201573Srgrimesprotected int 12184260Sobriensig_init(EditLine *el) 1221573Srgrimes{ 123237448Spfg size_t i; 124237448Spfg sigset_t *nset, oset; 1251573Srgrimes 126237448Spfg el->el_signal = el_malloc(sizeof(*el->el_signal)); 127237448Spfg if (el->el_signal == NULL) 128237448Spfg return -1; 129237448Spfg 130237448Spfg nset = &el->el_signal->sig_set; 131237448Spfg (void) sigemptyset(nset); 132237448Spfg#define _DO(a) (void) sigaddset(nset, a); 13384260Sobrien ALLSIGS 13484260Sobrien#undef _DO 135237448Spfg (void) sigprocmask(SIG_BLOCK, nset, &oset); 1361573Srgrimes 137237448Spfg for (i = 0; sighdl[i] != -1; i++) { 138237448Spfg el->el_signal->sig_action[i].sa_handler = SIG_ERR; 139237448Spfg el->el_signal->sig_action[i].sa_flags = 0; 140237448Spfg sigemptyset(&el->el_signal->sig_action[i].sa_mask); 141237448Spfg } 1421573Srgrimes 14384260Sobrien (void) sigprocmask(SIG_SETMASK, &oset, NULL); 1441573Srgrimes 145237448Spfg return 0; 1461573Srgrimes} 1471573Srgrimes 1481573Srgrimes 1491573Srgrimes/* sig_end(): 1501573Srgrimes * Clear all signal stuff 1511573Srgrimes */ 1521573Srgrimesprotected void 15384260Sobriensig_end(EditLine *el) 1541573Srgrimes{ 15584260Sobrien 156276881Sbapt el_free(el->el_signal); 15784260Sobrien el->el_signal = NULL; 1581573Srgrimes} 1591573Srgrimes 1601573Srgrimes 1611573Srgrimes/* sig_set(): 1621573Srgrimes * set all the signal handlers 1631573Srgrimes */ 1641573Srgrimesprotected void 16584260Sobriensig_set(EditLine *el) 1661573Srgrimes{ 167237448Spfg size_t i; 168237448Spfg sigset_t oset; 169237448Spfg struct sigaction osa, nsa; 1701573Srgrimes 171237448Spfg nsa.sa_handler = sig_handler; 172238378Spfg nsa.sa_flags = 0; 173237448Spfg sigemptyset(&nsa.sa_mask); 1741573Srgrimes 175237448Spfg (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset); 176237448Spfg 17784260Sobrien for (i = 0; sighdl[i] != -1; i++) { 17884260Sobrien /* This could happen if we get interrupted */ 179237448Spfg if (sigaction(sighdl[i], &nsa, &osa) != -1 && 180237448Spfg osa.sa_handler != sig_handler) 181237448Spfg el->el_signal->sig_action[i] = osa; 18284260Sobrien } 18384260Sobrien sel = el; 18484260Sobrien (void) sigprocmask(SIG_SETMASK, &oset, NULL); 1851573Srgrimes} 1861573Srgrimes 1871573Srgrimes 1881573Srgrimes/* sig_clr(): 1891573Srgrimes * clear all the signal handlers 1901573Srgrimes */ 1911573Srgrimesprotected void 19284260Sobriensig_clr(EditLine *el) 1931573Srgrimes{ 194237448Spfg size_t i; 195237448Spfg sigset_t oset; 1961573Srgrimes 197237448Spfg (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset); 1981573Srgrimes 19984260Sobrien for (i = 0; sighdl[i] != -1; i++) 200237448Spfg if (el->el_signal->sig_action[i].sa_handler != SIG_ERR) 201237448Spfg (void)sigaction(sighdl[i], 202237448Spfg &el->el_signal->sig_action[i], NULL); 2031573Srgrimes 20484260Sobrien sel = NULL; /* we are going to die if the handler is 20584260Sobrien * called */ 206237448Spfg (void)sigprocmask(SIG_SETMASK, &oset, NULL); 2071573Srgrimes} 208