xref: /csrg-svn/lib/libedit/sig.c (revision 61275)
154233Sbostic /*-
2*61275Sbostic  * Copyright (c) 1992, 1993
3*61275Sbostic  *	The Regents of the University of California.  All rights reserved.
454233Sbostic  *
554233Sbostic  * This code is derived from software contributed to Berkeley by
654233Sbostic  * Christos Zoulas of Cornell University.
754233Sbostic  *
854233Sbostic  * %sccs.include.redist.c%
954233Sbostic  */
1054233Sbostic 
1154624Schristos #if !defined(lint) && !defined(SCCSID)
12*61275Sbostic static char sccsid[] = "@(#)sig.c	8.1 (Berkeley) 06/04/93";
1354624Schristos #endif /* not lint && not SCCSID */
1454233Sbostic 
1554233Sbostic /*
1654624Schristos  * sig.c: Signal handling stuff.
1754624Schristos  *	  our policy is to trap all signals, set a good state
1854624Schristos  *	  and pass the ball to our caller.
1954233Sbostic  */
2054233Sbostic #include "sys.h"
2154233Sbostic #include "el.h"
2254233Sbostic #include <stdlib.h>
2354233Sbostic 
2454233Sbostic private EditLine *sel = NULL;
2554233Sbostic 
2654233Sbostic private int sighdl[] = {
2754233Sbostic #define _DO(a)	(a),
2854233Sbostic     ALLSIGS
2954233Sbostic #undef _DO
3054233Sbostic     -1
3154233Sbostic };
3254233Sbostic 
3354233Sbostic private void sig_handler	__P((int));
3454233Sbostic 
3554233Sbostic /* sig_handler():
3654233Sbostic  *	This is the handler called for all signals
3754233Sbostic  *	XXX: we cannot pass any data so we just store the old editline
3854233Sbostic  *	state in a private variable
3954233Sbostic  */
4054233Sbostic private void
sig_handler(signo)4154233Sbostic sig_handler(signo)
4254233Sbostic     int signo;
4354233Sbostic {
4454233Sbostic     int i;
4554233Sbostic     sigset_t nset, oset;
4654233Sbostic 
4754233Sbostic     (void) sigemptyset(&nset);
4854233Sbostic     (void) sigaddset(&nset, signo);
4954233Sbostic     (void) sigprocmask(SIG_BLOCK, &nset, &oset);
5054233Sbostic 
5154233Sbostic     switch (signo) {
5254233Sbostic     case SIGCONT:
5354233Sbostic 	tty_rawmode(sel);
5454233Sbostic 	if (ed_redisplay(sel, 0) == CC_REFRESH)
5554233Sbostic 	    re_refresh(sel);
5654233Sbostic 	term__flush();
5754233Sbostic 	break;
5854233Sbostic 
5954233Sbostic     case SIGWINCH:
6054233Sbostic 	el_resize(sel);
6154233Sbostic 	break;
6254233Sbostic 
6354233Sbostic     default:
6454233Sbostic 	tty_cookedmode(sel);
6554233Sbostic 	break;
6654233Sbostic     }
6754233Sbostic 
6854233Sbostic     for (i = 0; sighdl[i] != -1; i++)
6954233Sbostic 	if (signo == sighdl[i])
7054233Sbostic 	    break;
7154233Sbostic 
7254233Sbostic     (void) signal(signo, sel->el_signal[i]);
7354233Sbostic     (void) sigprocmask(SIG_SETMASK, &oset, NULL);
7454233Sbostic     (void) kill(0, signo);
7554233Sbostic }
7654233Sbostic 
7754233Sbostic 
7854233Sbostic /* sig_init():
7954233Sbostic  *	Initialize all signal stuff
8054233Sbostic  */
8154233Sbostic protected int
sig_init(el)8254233Sbostic sig_init(el)
8354233Sbostic     EditLine *el;
8454233Sbostic {
8554233Sbostic     int i;
8654233Sbostic     sigset_t nset, oset;
8754233Sbostic 
8854233Sbostic     (void) sigemptyset(&nset);
8954233Sbostic #define _DO(a) (void) sigaddset(&nset, SIGWINCH);
9054233Sbostic     ALLSIGS
9154233Sbostic #undef _DO
9254233Sbostic     (void) sigprocmask(SIG_BLOCK, &nset, &oset);
9354233Sbostic 
9454233Sbostic #define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(sig_t))
9554233Sbostic 
9654233Sbostic     el->el_signal = (sig_t *) el_malloc(SIGSIZE);
9754233Sbostic     for (i = 0; sighdl[i] != -1; i++)
9854233Sbostic 	el->el_signal[i] = BADSIG;
9954233Sbostic 
10054233Sbostic     (void) sigprocmask(SIG_SETMASK, &oset, NULL);
10154233Sbostic 
10254233Sbostic     return 0;
10354233Sbostic }
10454233Sbostic 
10554233Sbostic 
10654233Sbostic /* sig_end():
10754233Sbostic  *	Clear all signal stuff
10854233Sbostic  */
10954233Sbostic protected void
sig_end(el)11054233Sbostic sig_end(el)
11154233Sbostic     EditLine *el;
11254233Sbostic {
11354233Sbostic     el_free((ptr_t) el->el_signal);
11454233Sbostic     el->el_signal = NULL;
11554233Sbostic }
11654233Sbostic 
11754233Sbostic 
11854233Sbostic /* sig_set():
11954233Sbostic  *	set all the signal handlers
12054233Sbostic  */
12154233Sbostic protected void
sig_set(el)12254233Sbostic sig_set(el)
12354233Sbostic     EditLine *el;
12454233Sbostic {
12554233Sbostic     int i;
12654233Sbostic     sigset_t nset, oset;
12754233Sbostic 
12854233Sbostic     (void) sigemptyset(&nset);
12954233Sbostic #define _DO(a) (void) sigaddset(&nset, SIGWINCH);
13054233Sbostic     ALLSIGS
13154233Sbostic #undef _DO
13254233Sbostic     (void) sigprocmask(SIG_BLOCK, &nset, &oset);
13354233Sbostic 
13454233Sbostic     for (i = 0; sighdl[i] != -1; i++) {
13554233Sbostic 	sig_t s;
13654233Sbostic 	/* This could happen if we get interrupted */
13754233Sbostic 	if ((s = signal(sighdl[i], sig_handler)) != sig_handler)
13854233Sbostic 	    el->el_signal[i] = s;
13954233Sbostic     }
14054233Sbostic     sel = el;
14154233Sbostic     (void) sigprocmask(SIG_SETMASK, &oset, NULL);
14254233Sbostic }
14354233Sbostic 
14454233Sbostic 
14554233Sbostic /* sig_clr():
14654233Sbostic  *	clear all the signal handlers
14754233Sbostic  */
14854233Sbostic protected void
sig_clr(el)14954233Sbostic sig_clr(el)
15054233Sbostic     EditLine *el;
15154233Sbostic {
15254233Sbostic     int i;
15354233Sbostic     sigset_t nset, oset;
15454233Sbostic 
15554233Sbostic     (void) sigemptyset(&nset);
15654233Sbostic #define _DO(a) (void) sigaddset(&nset, SIGWINCH);
15754233Sbostic     ALLSIGS
15854233Sbostic #undef _DO
15954233Sbostic     (void) sigprocmask(SIG_BLOCK, &nset, &oset);
16054233Sbostic 
16154233Sbostic     for (i = 0; sighdl[i] != -1; i++)
16254233Sbostic 	if (el->el_signal[i] != BADSIG)
16354233Sbostic 	    (void) signal(sighdl[i], el->el_signal[i]);
16454233Sbostic 
16554233Sbostic     sel = NULL;	/* we are going to die if the handler is called */
16654233Sbostic     (void) sigprocmask(SIG_SETMASK, &oset, NULL);
16754233Sbostic }
168