sig.c revision 148834
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 * 32148834Sstefanf * $NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc 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: head/lib/libedit/sig.c 148834 2005-08-07 20:55:59Z stefanf $"); 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 7684260Sobrien switch (signo) { 7784260Sobrien case SIGCONT: 7884260Sobrien tty_rawmode(sel); 7984260Sobrien if (ed_redisplay(sel, 0) == CC_REFRESH) 8084260Sobrien re_refresh(sel); 8184260Sobrien term__flush(); 8284260Sobrien break; 831573Srgrimes 8484260Sobrien case SIGWINCH: 8584260Sobrien el_resize(sel); 8684260Sobrien break; 871573Srgrimes 8884260Sobrien default: 8984260Sobrien tty_cookedmode(sel); 9084260Sobrien break; 9184260Sobrien } 921573Srgrimes 9384260Sobrien for (i = 0; sighdl[i] != -1; i++) 9484260Sobrien if (signo == sighdl[i]) 9584260Sobrien break; 961573Srgrimes 9784260Sobrien (void) signal(signo, sel->el_signal[i]); 9884260Sobrien (void) sigprocmask(SIG_SETMASK, &oset, NULL); 9984260Sobrien (void) kill(0, signo); 1001573Srgrimes} 1011573Srgrimes 1021573Srgrimes 1031573Srgrimes/* sig_init(): 1041573Srgrimes * Initialize all signal stuff 1051573Srgrimes */ 1061573Srgrimesprotected int 10784260Sobriensig_init(EditLine *el) 1081573Srgrimes{ 10984260Sobrien int i; 11084260Sobrien sigset_t nset, oset; 1111573Srgrimes 11284260Sobrien (void) sigemptyset(&nset); 11384260Sobrien#define _DO(a) (void) sigaddset(&nset, a); 11484260Sobrien ALLSIGS 11584260Sobrien#undef _DO 11684260Sobrien (void) sigprocmask(SIG_BLOCK, &nset, &oset); 1171573Srgrimes 118148834Sstefanf#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(el_signalhandler_t)) 1191573Srgrimes 120148834Sstefanf el->el_signal = (el_signalhandler_t *) el_malloc(SIGSIZE); 12184260Sobrien if (el->el_signal == NULL) 12284260Sobrien return (-1); 12384260Sobrien for (i = 0; sighdl[i] != -1; i++) 12484260Sobrien el->el_signal[i] = SIG_ERR; 1251573Srgrimes 12684260Sobrien (void) sigprocmask(SIG_SETMASK, &oset, NULL); 1271573Srgrimes 12884260Sobrien return (0); 1291573Srgrimes} 1301573Srgrimes 1311573Srgrimes 1321573Srgrimes/* sig_end(): 1331573Srgrimes * Clear all signal stuff 1341573Srgrimes */ 1351573Srgrimesprotected void 13684260Sobriensig_end(EditLine *el) 1371573Srgrimes{ 13884260Sobrien 13984260Sobrien el_free((ptr_t) el->el_signal); 14084260Sobrien el->el_signal = NULL; 1411573Srgrimes} 1421573Srgrimes 1431573Srgrimes 1441573Srgrimes/* sig_set(): 1451573Srgrimes * set all the signal handlers 1461573Srgrimes */ 1471573Srgrimesprotected void 14884260Sobriensig_set(EditLine *el) 1491573Srgrimes{ 15084260Sobrien int i; 15184260Sobrien sigset_t nset, oset; 1521573Srgrimes 15384260Sobrien (void) sigemptyset(&nset); 15484260Sobrien#define _DO(a) (void) sigaddset(&nset, a); 15584260Sobrien ALLSIGS 15684260Sobrien#undef _DO 15784260Sobrien (void) sigprocmask(SIG_BLOCK, &nset, &oset); 1581573Srgrimes 15984260Sobrien for (i = 0; sighdl[i] != -1; i++) { 160148834Sstefanf el_signalhandler_t s; 16184260Sobrien /* This could happen if we get interrupted */ 16284260Sobrien if ((s = signal(sighdl[i], sig_handler)) != sig_handler) 16384260Sobrien el->el_signal[i] = s; 16484260Sobrien } 16584260Sobrien sel = el; 16684260Sobrien (void) sigprocmask(SIG_SETMASK, &oset, NULL); 1671573Srgrimes} 1681573Srgrimes 1691573Srgrimes 1701573Srgrimes/* sig_clr(): 1711573Srgrimes * clear all the signal handlers 1721573Srgrimes */ 1731573Srgrimesprotected void 17484260Sobriensig_clr(EditLine *el) 1751573Srgrimes{ 17684260Sobrien int i; 17784260Sobrien sigset_t nset, oset; 1781573Srgrimes 17984260Sobrien (void) sigemptyset(&nset); 18084260Sobrien#define _DO(a) (void) sigaddset(&nset, a); 18184260Sobrien ALLSIGS 18284260Sobrien#undef _DO 18384260Sobrien (void) sigprocmask(SIG_BLOCK, &nset, &oset); 1841573Srgrimes 18584260Sobrien for (i = 0; sighdl[i] != -1; i++) 18684260Sobrien if (el->el_signal[i] != SIG_ERR) 18784260Sobrien (void) signal(sighdl[i], el->el_signal[i]); 1881573Srgrimes 18984260Sobrien sel = NULL; /* we are going to die if the handler is 19084260Sobrien * called */ 19184260Sobrien (void) sigprocmask(SIG_SETMASK, &oset, NULL); 1921573Srgrimes} 193