112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*	$NetBSD: sig.c,v 1.17 2011/07/28 20:50:55 christos Exp $	*/
212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*-
412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Copyright (c) 1992, 1993
512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	The Regents of the University of California.  All rights reserved.
612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * This code is derived from software contributed to Berkeley by
812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Christos Zoulas of Cornell University.
912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
1012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * Redistribution and use in source and binary forms, with or without
1112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * modification, are permitted provided that the following conditions
1212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * are met:
1312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 1. Redistributions of source code must retain the above copyright
1412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    notice, this list of conditions and the following disclaimer.
1512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 2. Redistributions in binary form must reproduce the above copyright
1612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    notice, this list of conditions and the following disclaimer in the
1712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    documentation and/or other materials provided with the distribution.
1812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * 3. Neither the name of the University nor the names of its contributors
1912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    may be used to endorse or promote products derived from this software
2012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *    without specific prior written permission.
2112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *
2212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * SUCH DAMAGE.
3312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
3412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
3512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "config.h"
3612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if !defined(lint) && !defined(SCCSID)
3712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#if 0
3812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialastatic char sccsid[] = "@(#)sig.c	8.1 (Berkeley) 6/4/93";
3912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#else
4012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala__RCSID("$NetBSD: sig.c,v 1.17 2011/07/28 20:50:55 christos Exp $");
4112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif
4212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#endif /* not lint && not SCCSID */
4312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
4412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/*
4512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala * sig.c: Signal handling stuff.
4612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	  our policy is to trap all signals, set a good state
4712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	  and pass the ball to our caller.
4812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
4912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include "el.h"
5012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#include <stdlib.h>
5112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
5212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate EditLine *sel = NULL;
5312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
5412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate const int sighdl[] = {
5512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	_DO(a)	(a),
5612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ALLSIGS
5712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#undef	_DO
5812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	- 1
5912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala};
6012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
6112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void sig_handler(int);
6212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
6312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* sig_handler():
6412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	This is the handler called for all signals
6512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	XXX: we cannot pass any data so we just store the old editline
6612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	state in a private variable
6712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
6812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprivate void
6912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialasig_handler(int signo)
7012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
7112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	int i;
7212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sigset_t nset, oset;
7312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
7412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigemptyset(&nset);
7512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigaddset(&nset, signo);
7612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigprocmask(SIG_BLOCK, &nset, &oset);
7712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
7812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sel->el_signal->sig_no = signo;
7912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
8012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	switch (signo) {
8112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case SIGCONT:
8212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		tty_rawmode(sel);
8312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (ed_redisplay(sel, 0) == CC_REFRESH)
8412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			re_refresh(sel);
8512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		terminal__flush(sel);
8612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
8712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
8812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	case SIGWINCH:
8912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el_resize(sel);
9012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
9112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
9212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	default:
9312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		tty_cookedmode(sel);
9412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		break;
9512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
9612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
9712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; sighdl[i] != -1; i++)
9812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (signo == sighdl[i])
9912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			break;
10012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
10112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigaction(signo, &sel->el_signal->sig_action[i], NULL);
10212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sel->el_signal->sig_action[i].sa_handler = SIG_ERR;
10312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sel->el_signal->sig_action[i].sa_flags = 0;
10412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sigemptyset(&sel->el_signal->sig_action[i].sa_mask);
10512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
10612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) kill(0, signo);
10712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
10812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
10912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
11012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* sig_init():
11112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Initialize all signal stuff
11212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
11312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected int
11412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialasig_init(EditLine *el)
11512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
11612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	size_t i;
11712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sigset_t *nset, oset;
11812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
11912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_signal = el_malloc(sizeof(*el->el_signal));
12012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	if (el->el_signal == NULL)
12112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		return -1;
12212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
12312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	nset = &el->el_signal->sig_set;
12412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigemptyset(nset);
12512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#define	_DO(a) (void) sigaddset(nset, a);
12612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	ALLSIGS
12712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala#undef	_DO
12812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigprocmask(SIG_BLOCK, nset, &oset);
12912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
13012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; sighdl[i] != -1; i++) {
13112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_signal->sig_action[i].sa_handler = SIG_ERR;
13212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		el->el_signal->sig_action[i].sa_flags = 0;
13312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		sigemptyset(&el->el_signal->sig_action[i].sa_mask);
13412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
13512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
13612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
13712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
13812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	return 0;
13912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
14012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
14112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
14212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* sig_end():
14312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	Clear all signal stuff
14412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
14512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
14612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialasig_end(EditLine *el)
14712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
14812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
14912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el_free(el->el_signal);
15012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	el->el_signal = NULL;
15112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
15212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
15312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
15412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* sig_set():
15512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	set all the signal handlers
15612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
15712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
15812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialasig_set(EditLine *el)
15912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
16012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	size_t i;
16112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sigset_t oset;
16212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	struct sigaction osa, nsa;
16312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
16412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	nsa.sa_handler = sig_handler;
16512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	nsa.sa_flags = 0;
16612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sigemptyset(&nsa.sa_mask);
16712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
16812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
16912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
17012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; sighdl[i] != -1; i++) {
17112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		/* This could happen if we get interrupted */
17212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (sigaction(sighdl[i], &nsa, &osa) != -1 &&
17312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		    osa.sa_handler != sig_handler)
17412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			el->el_signal->sig_action[i] = osa;
17512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	}
17612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sel = el;
17712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
17812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
17912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
18012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
18112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala/* sig_clr():
18212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala *	clear all the signal handlers
18312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala */
18412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialaprotected void
18512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fialasig_clr(EditLine *el)
18612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala{
18712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	size_t i;
18812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sigset_t oset;
18912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
19012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
19112e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
19212e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	for (i = 0; sighdl[i] != -1; i++)
19312e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala		if (el->el_signal->sig_action[i].sa_handler != SIG_ERR)
19412e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			(void)sigaction(sighdl[i],
19512e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala			    &el->el_signal->sig_action[i], NULL);
19612e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala
19712e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	sel = NULL;		/* we are going to die if the handler is
19812e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala				 * called */
19912e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
20012e21689bc88a77c7b5b9b220fec31e049e5ec0fTodd Fiala}
201