xref: /original-bsd/lib/libedit/sig.c (revision c3e32dec)
1 /*-
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Christos Zoulas of Cornell University.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 #if !defined(lint) && !defined(SCCSID)
12 static char sccsid[] = "@(#)sig.c	8.1 (Berkeley) 06/04/93";
13 #endif /* not lint && not SCCSID */
14 
15 /*
16  * sig.c: Signal handling stuff.
17  *	  our policy is to trap all signals, set a good state
18  *	  and pass the ball to our caller.
19  */
20 #include "sys.h"
21 #include "el.h"
22 #include <stdlib.h>
23 
24 private EditLine *sel = NULL;
25 
26 private int sighdl[] = {
27 #define _DO(a)	(a),
28     ALLSIGS
29 #undef _DO
30     -1
31 };
32 
33 private void sig_handler	__P((int));
34 
35 /* sig_handler():
36  *	This is the handler called for all signals
37  *	XXX: we cannot pass any data so we just store the old editline
38  *	state in a private variable
39  */
40 private void
41 sig_handler(signo)
42     int signo;
43 {
44     int i;
45     sigset_t nset, oset;
46 
47     (void) sigemptyset(&nset);
48     (void) sigaddset(&nset, signo);
49     (void) sigprocmask(SIG_BLOCK, &nset, &oset);
50 
51     switch (signo) {
52     case SIGCONT:
53 	tty_rawmode(sel);
54 	if (ed_redisplay(sel, 0) == CC_REFRESH)
55 	    re_refresh(sel);
56 	term__flush();
57 	break;
58 
59     case SIGWINCH:
60 	el_resize(sel);
61 	break;
62 
63     default:
64 	tty_cookedmode(sel);
65 	break;
66     }
67 
68     for (i = 0; sighdl[i] != -1; i++)
69 	if (signo == sighdl[i])
70 	    break;
71 
72     (void) signal(signo, sel->el_signal[i]);
73     (void) sigprocmask(SIG_SETMASK, &oset, NULL);
74     (void) kill(0, signo);
75 }
76 
77 
78 /* sig_init():
79  *	Initialize all signal stuff
80  */
81 protected int
82 sig_init(el)
83     EditLine *el;
84 {
85     int i;
86     sigset_t nset, oset;
87 
88     (void) sigemptyset(&nset);
89 #define _DO(a) (void) sigaddset(&nset, SIGWINCH);
90     ALLSIGS
91 #undef _DO
92     (void) sigprocmask(SIG_BLOCK, &nset, &oset);
93 
94 #define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(sig_t))
95 
96     el->el_signal = (sig_t *) el_malloc(SIGSIZE);
97     for (i = 0; sighdl[i] != -1; i++)
98 	el->el_signal[i] = BADSIG;
99 
100     (void) sigprocmask(SIG_SETMASK, &oset, NULL);
101 
102     return 0;
103 }
104 
105 
106 /* sig_end():
107  *	Clear all signal stuff
108  */
109 protected void
110 sig_end(el)
111     EditLine *el;
112 {
113     el_free((ptr_t) el->el_signal);
114     el->el_signal = NULL;
115 }
116 
117 
118 /* sig_set():
119  *	set all the signal handlers
120  */
121 protected void
122 sig_set(el)
123     EditLine *el;
124 {
125     int i;
126     sigset_t nset, oset;
127 
128     (void) sigemptyset(&nset);
129 #define _DO(a) (void) sigaddset(&nset, SIGWINCH);
130     ALLSIGS
131 #undef _DO
132     (void) sigprocmask(SIG_BLOCK, &nset, &oset);
133 
134     for (i = 0; sighdl[i] != -1; i++) {
135 	sig_t s;
136 	/* This could happen if we get interrupted */
137 	if ((s = signal(sighdl[i], sig_handler)) != sig_handler)
138 	    el->el_signal[i] = s;
139     }
140     sel = el;
141     (void) sigprocmask(SIG_SETMASK, &oset, NULL);
142 }
143 
144 
145 /* sig_clr():
146  *	clear all the signal handlers
147  */
148 protected void
149 sig_clr(el)
150     EditLine *el;
151 {
152     int i;
153     sigset_t nset, oset;
154 
155     (void) sigemptyset(&nset);
156 #define _DO(a) (void) sigaddset(&nset, SIGWINCH);
157     ALLSIGS
158 #undef _DO
159     (void) sigprocmask(SIG_BLOCK, &nset, &oset);
160 
161     for (i = 0; sighdl[i] != -1; i++)
162 	if (el->el_signal[i] != BADSIG)
163 	    (void) signal(sighdl[i], el->el_signal[i]);
164 
165     sel = NULL;	/* we are going to die if the handler is called */
166     (void) sigprocmask(SIG_SETMASK, &oset, NULL);
167 }
168