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