sig.c revision 148834
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.
16148834Sstefanf * 3. Neither the name of the University nor the names of its contributors
171573Srgrimes *    may be used to endorse or promote products derived from this software
181573Srgrimes *    without specific prior written permission.
191573Srgrimes *
201573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
211573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
221573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
231573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
241573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
251573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
261573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
271573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
281573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
291573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
301573Srgrimes * SUCH DAMAGE.
3184260Sobrien *
32148834Sstefanf *	$NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $
331573Srgrimes */
341573Srgrimes
351573Srgrimes#if !defined(lint) && !defined(SCCSID)
361573Srgrimesstatic char sccsid[] = "@(#)sig.c	8.1 (Berkeley) 6/4/93";
371573Srgrimes#endif /* not lint && not SCCSID */
3884260Sobrien#include <sys/cdefs.h>
3984260Sobrien__FBSDID("$FreeBSD: head/lib/libedit/sig.c 148834 2005-08-07 20:55:59Z stefanf $");
401573Srgrimes
411573Srgrimes/*
421573Srgrimes * sig.c: Signal handling stuff.
431573Srgrimes *	  our policy is to trap all signals, set a good state
441573Srgrimes *	  and pass the ball to our caller.
451573Srgrimes */
461573Srgrimes#include "sys.h"
471573Srgrimes#include "el.h"
481573Srgrimes#include <stdlib.h>
491573Srgrimes
501573Srgrimesprivate EditLine *sel = NULL;
511573Srgrimes
5284260Sobrienprivate const int sighdl[] = {
5384260Sobrien#define	_DO(a)	(a),
5484260Sobrien	ALLSIGS
5584260Sobrien#undef	_DO
5684260Sobrien	- 1
571573Srgrimes};
581573Srgrimes
5984260Sobrienprivate void sig_handler(int);
601573Srgrimes
611573Srgrimes/* sig_handler():
621573Srgrimes *	This is the handler called for all signals
631573Srgrimes *	XXX: we cannot pass any data so we just store the old editline
641573Srgrimes *	state in a private variable
651573Srgrimes */
661573Srgrimesprivate void
6784260Sobriensig_handler(int signo)
681573Srgrimes{
6984260Sobrien	int i;
7084260Sobrien	sigset_t nset, oset;
711573Srgrimes
7284260Sobrien	(void) sigemptyset(&nset);
7384260Sobrien	(void) sigaddset(&nset, signo);
7484260Sobrien	(void) sigprocmask(SIG_BLOCK, &nset, &oset);
751573Srgrimes
7684260Sobrien	switch (signo) {
7784260Sobrien	case SIGCONT:
7884260Sobrien		tty_rawmode(sel);
7984260Sobrien		if (ed_redisplay(sel, 0) == CC_REFRESH)
8084260Sobrien			re_refresh(sel);
8184260Sobrien		term__flush();
8284260Sobrien		break;
831573Srgrimes
8484260Sobrien	case SIGWINCH:
8584260Sobrien		el_resize(sel);
8684260Sobrien		break;
871573Srgrimes
8884260Sobrien	default:
8984260Sobrien		tty_cookedmode(sel);
9084260Sobrien		break;
9184260Sobrien	}
921573Srgrimes
9384260Sobrien	for (i = 0; sighdl[i] != -1; i++)
9484260Sobrien		if (signo == sighdl[i])
9584260Sobrien			break;
961573Srgrimes
9784260Sobrien	(void) signal(signo, sel->el_signal[i]);
9884260Sobrien	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
9984260Sobrien	(void) kill(0, signo);
1001573Srgrimes}
1011573Srgrimes
1021573Srgrimes
1031573Srgrimes/* sig_init():
1041573Srgrimes *	Initialize all signal stuff
1051573Srgrimes */
1061573Srgrimesprotected int
10784260Sobriensig_init(EditLine *el)
1081573Srgrimes{
10984260Sobrien	int i;
11084260Sobrien	sigset_t nset, oset;
1111573Srgrimes
11284260Sobrien	(void) sigemptyset(&nset);
11384260Sobrien#define	_DO(a) (void) sigaddset(&nset, a);
11484260Sobrien	ALLSIGS
11584260Sobrien#undef	_DO
11684260Sobrien	    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
1171573Srgrimes
118148834Sstefanf#define	SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(el_signalhandler_t))
1191573Srgrimes
120148834Sstefanf	el->el_signal = (el_signalhandler_t *) el_malloc(SIGSIZE);
12184260Sobrien	if (el->el_signal == NULL)
12284260Sobrien		return (-1);
12384260Sobrien	for (i = 0; sighdl[i] != -1; i++)
12484260Sobrien		el->el_signal[i] = SIG_ERR;
1251573Srgrimes
12684260Sobrien	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
1271573Srgrimes
12884260Sobrien	return (0);
1291573Srgrimes}
1301573Srgrimes
1311573Srgrimes
1321573Srgrimes/* sig_end():
1331573Srgrimes *	Clear all signal stuff
1341573Srgrimes */
1351573Srgrimesprotected void
13684260Sobriensig_end(EditLine *el)
1371573Srgrimes{
13884260Sobrien
13984260Sobrien	el_free((ptr_t) el->el_signal);
14084260Sobrien	el->el_signal = NULL;
1411573Srgrimes}
1421573Srgrimes
1431573Srgrimes
1441573Srgrimes/* sig_set():
1451573Srgrimes *	set all the signal handlers
1461573Srgrimes */
1471573Srgrimesprotected void
14884260Sobriensig_set(EditLine *el)
1491573Srgrimes{
15084260Sobrien	int i;
15184260Sobrien	sigset_t nset, oset;
1521573Srgrimes
15384260Sobrien	(void) sigemptyset(&nset);
15484260Sobrien#define	_DO(a) (void) sigaddset(&nset, a);
15584260Sobrien	ALLSIGS
15684260Sobrien#undef	_DO
15784260Sobrien	    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
1581573Srgrimes
15984260Sobrien	for (i = 0; sighdl[i] != -1; i++) {
160148834Sstefanf		el_signalhandler_t s;
16184260Sobrien		/* This could happen if we get interrupted */
16284260Sobrien		if ((s = signal(sighdl[i], sig_handler)) != sig_handler)
16384260Sobrien			el->el_signal[i] = s;
16484260Sobrien	}
16584260Sobrien	sel = el;
16684260Sobrien	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
1671573Srgrimes}
1681573Srgrimes
1691573Srgrimes
1701573Srgrimes/* sig_clr():
1711573Srgrimes *	clear all the signal handlers
1721573Srgrimes */
1731573Srgrimesprotected void
17484260Sobriensig_clr(EditLine *el)
1751573Srgrimes{
17684260Sobrien	int i;
17784260Sobrien	sigset_t nset, oset;
1781573Srgrimes
17984260Sobrien	(void) sigemptyset(&nset);
18084260Sobrien#define	_DO(a) (void) sigaddset(&nset, a);
18184260Sobrien	ALLSIGS
18284260Sobrien#undef	_DO
18384260Sobrien	    (void) sigprocmask(SIG_BLOCK, &nset, &oset);
1841573Srgrimes
18584260Sobrien	for (i = 0; sighdl[i] != -1; i++)
18684260Sobrien		if (el->el_signal[i] != SIG_ERR)
18784260Sobrien			(void) signal(sighdl[i], el->el_signal[i]);
1881573Srgrimes
18984260Sobrien	sel = NULL;		/* we are going to die if the handler is
19084260Sobrien				 * called */
19184260Sobrien	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
1921573Srgrimes}
193