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