sig.c revision 84260
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.
161573Srgrimes * 3. All advertising materials mentioning features or use of this software
171573Srgrimes *    must display the following acknowledgement:
181573Srgrimes *	This product includes software developed by the University of
191573Srgrimes *	California, Berkeley and its contributors.
201573Srgrimes * 4. Neither the name of the University nor the names of its contributors
211573Srgrimes *    may be used to endorse or promote products derived from this software
221573Srgrimes *    without specific prior written permission.
231573Srgrimes *
241573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
251573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
261573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
271573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
281573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
291573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
301573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
311573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
321573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
331573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
341573Srgrimes * SUCH DAMAGE.
3584260Sobrien *
3684260Sobrien *	$NetBSD: sig.c,v 1.7 2001/01/04 15:55:03 christos Exp $
371573Srgrimes */
381573Srgrimes
391573Srgrimes#if !defined(lint) && !defined(SCCSID)
401573Srgrimesstatic char sccsid[] = "@(#)sig.c	8.1 (Berkeley) 6/4/93";
411573Srgrimes#endif /* not lint && not SCCSID */
4284260Sobrien#include <sys/cdefs.h>
4384260Sobrien__FBSDID("$FreeBSD: head/lib/libedit/sig.c 84260 2001-10-01 08:41:27Z obrien $");
441573Srgrimes
451573Srgrimes/*
461573Srgrimes * sig.c: Signal handling stuff.
471573Srgrimes *	  our policy is to trap all signals, set a good state
481573Srgrimes *	  and pass the ball to our caller.
491573Srgrimes */
501573Srgrimes#include "sys.h"
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
8084260Sobrien	switch (signo) {
8184260Sobrien	case SIGCONT:
8284260Sobrien		tty_rawmode(sel);
8384260Sobrien		if (ed_redisplay(sel, 0) == CC_REFRESH)
8484260Sobrien			re_refresh(sel);
8584260Sobrien		term__flush();
8684260Sobrien		break;
871573Srgrimes
8884260Sobrien	case SIGWINCH:
8984260Sobrien		el_resize(sel);
9084260Sobrien		break;
911573Srgrimes
9284260Sobrien	default:
9384260Sobrien		tty_cookedmode(sel);
9484260Sobrien		break;
9584260Sobrien	}
961573Srgrimes
9784260Sobrien	for (i = 0; sighdl[i] != -1; i++)
9884260Sobrien		if (signo == sighdl[i])
9984260Sobrien			break;
1001573Srgrimes
10184260Sobrien	(void) signal(signo, sel->el_signal[i]);
10284260Sobrien	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
10384260Sobrien	(void) kill(0, signo);
1041573Srgrimes}
1051573Srgrimes
1061573Srgrimes
1071573Srgrimes/* sig_init():
1081573Srgrimes *	Initialize all signal stuff
1091573Srgrimes */
1101573Srgrimesprotected int
11184260Sobriensig_init(EditLine *el)
1121573Srgrimes{
11384260Sobrien	int i;
11484260Sobrien	sigset_t nset, oset;
1151573Srgrimes
11684260Sobrien	(void) sigemptyset(&nset);
11784260Sobrien#define	_DO(a) (void) sigaddset(&nset, a);
11884260Sobrien	ALLSIGS
11984260Sobrien#undef	_DO
12084260Sobrien	    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
1211573Srgrimes
12284260Sobrien#define	SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(sig_t))
1231573Srgrimes
12484260Sobrien	el->el_signal = (sig_t *) el_malloc(SIGSIZE);
12584260Sobrien	if (el->el_signal == NULL)
12684260Sobrien		return (-1);
12784260Sobrien	for (i = 0; sighdl[i] != -1; i++)
12884260Sobrien		el->el_signal[i] = SIG_ERR;
1291573Srgrimes
13084260Sobrien	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
1311573Srgrimes
13284260Sobrien	return (0);
1331573Srgrimes}
1341573Srgrimes
1351573Srgrimes
1361573Srgrimes/* sig_end():
1371573Srgrimes *	Clear all signal stuff
1381573Srgrimes */
1391573Srgrimesprotected void
14084260Sobriensig_end(EditLine *el)
1411573Srgrimes{
14284260Sobrien
14384260Sobrien	el_free((ptr_t) el->el_signal);
14484260Sobrien	el->el_signal = NULL;
1451573Srgrimes}
1461573Srgrimes
1471573Srgrimes
1481573Srgrimes/* sig_set():
1491573Srgrimes *	set all the signal handlers
1501573Srgrimes */
1511573Srgrimesprotected void
15284260Sobriensig_set(EditLine *el)
1531573Srgrimes{
15484260Sobrien	int i;
15584260Sobrien	sigset_t nset, oset;
1561573Srgrimes
15784260Sobrien	(void) sigemptyset(&nset);
15884260Sobrien#define	_DO(a) (void) sigaddset(&nset, a);
15984260Sobrien	ALLSIGS
16084260Sobrien#undef	_DO
16184260Sobrien	    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
1621573Srgrimes
16384260Sobrien	for (i = 0; sighdl[i] != -1; i++) {
16484260Sobrien		sig_t s;
16584260Sobrien		/* This could happen if we get interrupted */
16684260Sobrien		if ((s = signal(sighdl[i], sig_handler)) != sig_handler)
16784260Sobrien			el->el_signal[i] = s;
16884260Sobrien	}
16984260Sobrien	sel = el;
17084260Sobrien	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
1711573Srgrimes}
1721573Srgrimes
1731573Srgrimes
1741573Srgrimes/* sig_clr():
1751573Srgrimes *	clear all the signal handlers
1761573Srgrimes */
1771573Srgrimesprotected void
17884260Sobriensig_clr(EditLine *el)
1791573Srgrimes{
18084260Sobrien	int i;
18184260Sobrien	sigset_t nset, oset;
1821573Srgrimes
18384260Sobrien	(void) sigemptyset(&nset);
18484260Sobrien#define	_DO(a) (void) sigaddset(&nset, a);
18584260Sobrien	ALLSIGS
18684260Sobrien#undef	_DO
18784260Sobrien	    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
1881573Srgrimes
18984260Sobrien	for (i = 0; sighdl[i] != -1; i++)
19084260Sobrien		if (el->el_signal[i] != SIG_ERR)
19184260Sobrien			(void) signal(sighdl[i], el->el_signal[i]);
1921573Srgrimes
19384260Sobrien	sel = NULL;		/* we are going to die if the handler is
19484260Sobrien				 * called */
19584260Sobrien	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
1961573Srgrimes}
197