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