xref: /dflybsd-src/contrib/libedit/src/sig.c (revision 12db70c8662d940c359926621f5dcef8a2365781)
1*12db70c8Szrj /*	$NetBSD: sig.c,v 1.26 2016/05/09 21:46:56 christos Exp $	*/
232fe07f8SJohn Marino 
332fe07f8SJohn Marino /*-
432fe07f8SJohn Marino  * Copyright (c) 1992, 1993
532fe07f8SJohn Marino  *	The Regents of the University of California.  All rights reserved.
632fe07f8SJohn Marino  *
732fe07f8SJohn Marino  * This code is derived from software contributed to Berkeley by
832fe07f8SJohn Marino  * Christos Zoulas of Cornell University.
932fe07f8SJohn Marino  *
1032fe07f8SJohn Marino  * Redistribution and use in source and binary forms, with or without
1132fe07f8SJohn Marino  * modification, are permitted provided that the following conditions
1232fe07f8SJohn Marino  * are met:
1332fe07f8SJohn Marino  * 1. Redistributions of source code must retain the above copyright
1432fe07f8SJohn Marino  *    notice, this list of conditions and the following disclaimer.
1532fe07f8SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
1632fe07f8SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
1732fe07f8SJohn Marino  *    documentation and/or other materials provided with the distribution.
1832fe07f8SJohn Marino  * 3. Neither the name of the University nor the names of its contributors
1932fe07f8SJohn Marino  *    may be used to endorse or promote products derived from this software
2032fe07f8SJohn Marino  *    without specific prior written permission.
2132fe07f8SJohn Marino  *
2232fe07f8SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2332fe07f8SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2432fe07f8SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2532fe07f8SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2632fe07f8SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2732fe07f8SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2832fe07f8SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2932fe07f8SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3032fe07f8SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3132fe07f8SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3232fe07f8SJohn Marino  * SUCH DAMAGE.
3332fe07f8SJohn Marino  */
3432fe07f8SJohn Marino 
3532fe07f8SJohn Marino #include "config.h"
3632fe07f8SJohn Marino #if !defined(lint) && !defined(SCCSID)
3732fe07f8SJohn Marino #if 0
3832fe07f8SJohn Marino static char sccsid[] = "@(#)sig.c	8.1 (Berkeley) 6/4/93";
3932fe07f8SJohn Marino #else
40*12db70c8Szrj __RCSID("$NetBSD: sig.c,v 1.26 2016/05/09 21:46:56 christos Exp $");
4132fe07f8SJohn Marino #endif
4232fe07f8SJohn Marino #endif /* not lint && not SCCSID */
4332fe07f8SJohn Marino 
4432fe07f8SJohn Marino /*
4532fe07f8SJohn Marino  * sig.c: Signal handling stuff.
4632fe07f8SJohn Marino  *	  our policy is to trap all signals, set a good state
4732fe07f8SJohn Marino  *	  and pass the ball to our caller.
4832fe07f8SJohn Marino  */
49*12db70c8Szrj #include <errno.h>
5032fe07f8SJohn Marino #include <stdlib.h>
5132fe07f8SJohn Marino 
52*12db70c8Szrj #include "el.h"
53*12db70c8Szrj #include "common.h"
5432fe07f8SJohn Marino 
55*12db70c8Szrj static EditLine *sel = NULL;
56*12db70c8Szrj 
57*12db70c8Szrj static const int sighdl[] = {
5832fe07f8SJohn Marino #define	_DO(a)	(a),
5932fe07f8SJohn Marino 	ALLSIGS
6032fe07f8SJohn Marino #undef	_DO
6132fe07f8SJohn Marino 	- 1
6232fe07f8SJohn Marino };
6332fe07f8SJohn Marino 
64*12db70c8Szrj static void sig_handler(int);
6532fe07f8SJohn Marino 
6632fe07f8SJohn Marino /* sig_handler():
6732fe07f8SJohn Marino  *	This is the handler called for all signals
6832fe07f8SJohn Marino  *	XXX: we cannot pass any data so we just store the old editline
6932fe07f8SJohn Marino  *	state in a private variable
7032fe07f8SJohn Marino  */
71*12db70c8Szrj static void
sig_handler(int signo)7232fe07f8SJohn Marino sig_handler(int signo)
7332fe07f8SJohn Marino {
74*12db70c8Szrj 	int i, save_errno;
7532fe07f8SJohn Marino 	sigset_t nset, oset;
7632fe07f8SJohn Marino 
77*12db70c8Szrj 	save_errno = errno;
7832fe07f8SJohn Marino 	(void) sigemptyset(&nset);
7932fe07f8SJohn Marino 	(void) sigaddset(&nset, signo);
8032fe07f8SJohn Marino 	(void) sigprocmask(SIG_BLOCK, &nset, &oset);
8132fe07f8SJohn Marino 
8232fe07f8SJohn Marino 	sel->el_signal->sig_no = signo;
8332fe07f8SJohn Marino 
8432fe07f8SJohn Marino 	switch (signo) {
8532fe07f8SJohn Marino 	case SIGCONT:
8632fe07f8SJohn Marino 		tty_rawmode(sel);
8732fe07f8SJohn Marino 		if (ed_redisplay(sel, 0) == CC_REFRESH)
8832fe07f8SJohn Marino 			re_refresh(sel);
8932fe07f8SJohn Marino 		terminal__flush(sel);
9032fe07f8SJohn Marino 		break;
9132fe07f8SJohn Marino 
9232fe07f8SJohn Marino 	case SIGWINCH:
9332fe07f8SJohn Marino 		el_resize(sel);
9432fe07f8SJohn Marino 		break;
9532fe07f8SJohn Marino 
9632fe07f8SJohn Marino 	default:
9732fe07f8SJohn Marino 		tty_cookedmode(sel);
9832fe07f8SJohn Marino 		break;
9932fe07f8SJohn Marino 	}
10032fe07f8SJohn Marino 
10132fe07f8SJohn Marino 	for (i = 0; sighdl[i] != -1; i++)
10232fe07f8SJohn Marino 		if (signo == sighdl[i])
10332fe07f8SJohn Marino 			break;
10432fe07f8SJohn Marino 
10532fe07f8SJohn Marino 	(void) sigaction(signo, &sel->el_signal->sig_action[i], NULL);
10632fe07f8SJohn Marino 	sel->el_signal->sig_action[i].sa_handler = SIG_ERR;
10732fe07f8SJohn Marino 	sel->el_signal->sig_action[i].sa_flags = 0;
10832fe07f8SJohn Marino 	sigemptyset(&sel->el_signal->sig_action[i].sa_mask);
10932fe07f8SJohn Marino 	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
11032fe07f8SJohn Marino 	(void) kill(0, signo);
111*12db70c8Szrj 	errno = save_errno;
11232fe07f8SJohn Marino }
11332fe07f8SJohn Marino 
11432fe07f8SJohn Marino 
11532fe07f8SJohn Marino /* sig_init():
11632fe07f8SJohn Marino  *	Initialize all signal stuff
11732fe07f8SJohn Marino  */
118*12db70c8Szrj libedit_private int
sig_init(EditLine * el)11932fe07f8SJohn Marino sig_init(EditLine *el)
12032fe07f8SJohn Marino {
12132fe07f8SJohn Marino 	size_t i;
12232fe07f8SJohn Marino 	sigset_t *nset, oset;
12332fe07f8SJohn Marino 
12432fe07f8SJohn Marino 	el->el_signal = el_malloc(sizeof(*el->el_signal));
12532fe07f8SJohn Marino 	if (el->el_signal == NULL)
12632fe07f8SJohn Marino 		return -1;
12732fe07f8SJohn Marino 
12832fe07f8SJohn Marino 	nset = &el->el_signal->sig_set;
12932fe07f8SJohn Marino 	(void) sigemptyset(nset);
13032fe07f8SJohn Marino #define	_DO(a) (void) sigaddset(nset, a);
13132fe07f8SJohn Marino 	ALLSIGS
13232fe07f8SJohn Marino #undef	_DO
13332fe07f8SJohn Marino 	(void) sigprocmask(SIG_BLOCK, nset, &oset);
13432fe07f8SJohn Marino 
13532fe07f8SJohn Marino 	for (i = 0; sighdl[i] != -1; i++) {
13632fe07f8SJohn Marino 		el->el_signal->sig_action[i].sa_handler = SIG_ERR;
13732fe07f8SJohn Marino 		el->el_signal->sig_action[i].sa_flags = 0;
13832fe07f8SJohn Marino 		sigemptyset(&el->el_signal->sig_action[i].sa_mask);
13932fe07f8SJohn Marino 	}
14032fe07f8SJohn Marino 
14132fe07f8SJohn Marino 	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
14232fe07f8SJohn Marino 
14332fe07f8SJohn Marino 	return 0;
14432fe07f8SJohn Marino }
14532fe07f8SJohn Marino 
14632fe07f8SJohn Marino 
14732fe07f8SJohn Marino /* sig_end():
14832fe07f8SJohn Marino  *	Clear all signal stuff
14932fe07f8SJohn Marino  */
150*12db70c8Szrj libedit_private void
sig_end(EditLine * el)15132fe07f8SJohn Marino sig_end(EditLine *el)
15232fe07f8SJohn Marino {
15332fe07f8SJohn Marino 
15432fe07f8SJohn Marino 	el_free(el->el_signal);
15532fe07f8SJohn Marino 	el->el_signal = NULL;
15632fe07f8SJohn Marino }
15732fe07f8SJohn Marino 
15832fe07f8SJohn Marino 
15932fe07f8SJohn Marino /* sig_set():
16032fe07f8SJohn Marino  *	set all the signal handlers
16132fe07f8SJohn Marino  */
162*12db70c8Szrj libedit_private void
sig_set(EditLine * el)16332fe07f8SJohn Marino sig_set(EditLine *el)
16432fe07f8SJohn Marino {
16532fe07f8SJohn Marino 	size_t i;
16632fe07f8SJohn Marino 	sigset_t oset;
16732fe07f8SJohn Marino 	struct sigaction osa, nsa;
16832fe07f8SJohn Marino 
16932fe07f8SJohn Marino 	nsa.sa_handler = sig_handler;
17032fe07f8SJohn Marino 	nsa.sa_flags = 0;
17132fe07f8SJohn Marino 	sigemptyset(&nsa.sa_mask);
17232fe07f8SJohn Marino 
17332fe07f8SJohn Marino 	(void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
17432fe07f8SJohn Marino 
17532fe07f8SJohn Marino 	for (i = 0; sighdl[i] != -1; i++) {
17632fe07f8SJohn Marino 		/* This could happen if we get interrupted */
17732fe07f8SJohn Marino 		if (sigaction(sighdl[i], &nsa, &osa) != -1 &&
17832fe07f8SJohn Marino 		    osa.sa_handler != sig_handler)
17932fe07f8SJohn Marino 			el->el_signal->sig_action[i] = osa;
18032fe07f8SJohn Marino 	}
18132fe07f8SJohn Marino 	sel = el;
18232fe07f8SJohn Marino 	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
18332fe07f8SJohn Marino }
18432fe07f8SJohn Marino 
18532fe07f8SJohn Marino 
18632fe07f8SJohn Marino /* sig_clr():
18732fe07f8SJohn Marino  *	clear all the signal handlers
18832fe07f8SJohn Marino  */
189*12db70c8Szrj libedit_private void
sig_clr(EditLine * el)19032fe07f8SJohn Marino sig_clr(EditLine *el)
19132fe07f8SJohn Marino {
19232fe07f8SJohn Marino 	size_t i;
19332fe07f8SJohn Marino 	sigset_t oset;
19432fe07f8SJohn Marino 
19532fe07f8SJohn Marino 	(void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
19632fe07f8SJohn Marino 
19732fe07f8SJohn Marino 	for (i = 0; sighdl[i] != -1; i++)
19832fe07f8SJohn Marino 		if (el->el_signal->sig_action[i].sa_handler != SIG_ERR)
19932fe07f8SJohn Marino 			(void)sigaction(sighdl[i],
20032fe07f8SJohn Marino 			    &el->el_signal->sig_action[i], NULL);
20132fe07f8SJohn Marino 
20232fe07f8SJohn Marino 	sel = NULL;		/* we are going to die if the handler is
20332fe07f8SJohn Marino 				 * called */
20432fe07f8SJohn Marino 	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
20532fe07f8SJohn Marino }
206