1: /* signal handling
2:
3: Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.
4:
5: This file is part of Gforth.
6:
7: Gforth is free software; you can redistribute it and/or
8: modify it under the terms of the GNU General Public License
9: as published by the Free Software Foundation; either version 2
10: of the License, or (at your option) any later version.
11:
12: This program is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with this program; if not, write to the Free Software
19: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20:
21: */
22:
23:
24: #define _GNU_SOURCE
25:
26: #include <stdio.h>
27: #include <signal.h>
28: #include <setjmp.h>
29: #include <string.h>
30: #include <stdlib.h>
31: #if !defined(apollo) && !defined(MSDOS)
32: #include <sys/ioctl.h>
33: #endif
34: #include "config.h"
35: #include "forth.h"
36: #include "io.h"
37:
38:
39: #define DEFAULTCOLS 80
40: #if defined(MSDOS) || defined (_WIN32)
41: #define DEFAULTROWS 25
42: #else
43: #define DEFAULTROWS 24
44: #endif
45:
46: UCell cols=DEFAULTCOLS;
47: UCell rows=DEFAULTROWS;
48:
49:
50: static void
51: graceful_exit (int sig)
52: {
53: deprep_terminal();
54: fprintf (stderr, "\n\n%s.\n", strsignal (sig));
55: exit (0x80|sig);
56: }
57:
58: jmp_buf throw_jmp_buf;
59:
60: static void
61: signal_throw(int sig)
62: {
63: int code;
64: struct {
65: int signal;
66: int throwcode;
67: } *p, throwtable[] = {
68: { SIGINT, -28 },
69: { SIGFPE, -55 },
70: #ifdef SIGBUS
71: { SIGBUS, -23 },
72: #endif
73: { SIGSEGV, -9 },
74: };
75: signal(sig,signal_throw);
76: for (code=-256-sig, p=throwtable; p<throwtable+(sizeof(throwtable)/sizeof(*p)); p++)
77: if (sig == p->signal) {
78: code = p->throwcode;
79: break;
80: }
81: longjmp(throw_jmp_buf,code); /* or use siglongjmp ? */
82: }
83:
84: #ifdef SIGCONT
85: static void termprep (int sig)
86: {
87: signal(sig,termprep);
88: terminal_prepped=0;
89: }
90: #endif
91:
92: void get_winsize()
93: {
94: #ifdef TIOCGWINSZ
95: struct winsize size;
96:
97: if (ioctl (1, TIOCGWINSZ, (char *) &size) >= 0) {
98: rows = size.ws_row;
99: cols = size.ws_col;
100: }
101: #else
102: char *s;
103: if ((s=getenv("LINES"))) {
104: rows=atoi(s);
105: if (rows==0)
106: rows=DEFAULTROWS;
107: }
108: if ((s=getenv("COLUMNS"))) {
109: rows=atoi(s);
110: if (rows==0)
111: cols=DEFAULTCOLS;
112: }
113: #endif
114: }
115:
116: #ifdef SIGWINCH
117: static void change_winsize(int sig)
118: {
119: signal(sig,change_winsize);
120: #ifdef TIOCGWINSZ
121: get_winsize();
122: #endif
123: }
124: #endif
125:
126: void install_signal_handlers (void)
127: {
128:
129: #if 0
130: /* these signals are handled right by default, no need to handle them;
131: they are listed here just for fun */
132: static short sigs_to_default [] = {
133: #ifdef SIGCHLD
134: SIGCHLD,
135: #endif
136: #ifdef SIGINFO
137: SIGINFO,
138: #endif
139: #ifdef SIGIO
140: SIGIO,
141: #endif
142: #ifdef SIGLOST
143: SIGLOST,
144: #endif
145: #ifdef SIGKILL
146: SIGKILL,
147: #endif
148: #ifdef SIGSTOP
149: SIGSTOP,
150: #endif
151: #ifdef SIGPWR
152: SIGPWR,
153: #endif
154: #ifdef SIGMSG
155: SIGMSG,
156: #endif
157: #ifdef SIGDANGER
158: SIGDANGER,
159: #endif
160: #ifdef SIGMIGRATE
161: SIGMIGRATE,
162: #endif
163: #ifdef SIGPRE
164: SIGPRE,
165: #endif
166: #ifdef SIGVIRT
167: SIGVIRT,
168: #endif
169: #ifdef SIGGRANT
170: SIGGRANT,
171: #endif
172: #ifdef SIGRETRACT
173: SIGRETRACT,
174: #endif
175: #ifdef SIGSOUND
176: SIGSOUND,
177: #endif
178: #ifdef SIGSAK
179: SIGSAK,
180: #endif
181: #ifdef SIGTSTP
182: SIGTSTP,
183: #endif
184: #ifdef SIGTTIN
185: SIGTTIN,
186: #endif
187: #ifdef SIGTTOU
188: SIGTTOU,
189: #endif
190: #ifdef SIGSTKFLT
191: SIGSTKFLT,
192: #endif
193: #ifdef SIGUNUSED
194: SIGUNUSED,
195: #endif
196: };
197: #endif
198:
199: static short sigs_to_throw [] = {
200: #ifdef SIGBREAK
201: SIGBREAK,
202: #endif
203: #ifdef SIGINT
204: SIGINT,
205: #endif
206: #ifdef SIGILL
207: SIGILL,
208: #endif
209: #ifdef SIGEMT
210: SIGEMT,
211: #endif
212: #ifdef SIGFPE
213: SIGFPE,
214: #endif
215: #ifdef SIGIOT
216: SIGIOT,
217: #endif
218: #ifdef SIGSEGV
219: SIGSEGV,
220: #endif
221: #ifdef SIGALRM
222: SIGALRM,
223: #endif
224: #ifdef SIGPIPE
225: SIGPIPE,
226: #endif
227: #ifdef SIGPOLL
228: SIGPOLL,
229: #endif
230: #ifdef SIGPROF
231: SIGPROF,
232: #endif
233: #ifdef SIGBUS
234: SIGBUS,
235: #endif
236: #ifdef SIGSYS
237: SIGSYS,
238: #endif
239: #ifdef SIGTRAP
240: SIGTRAP,
241: #endif
242: #ifdef SIGURG
243: SIGURG,
244: #endif
245: #ifdef SIGUSR1
246: SIGUSR1,
247: #endif
248: #ifdef SIGUSR2
249: SIGUSR2,
250: #endif
251: #ifdef SIGVTALRM
252: SIGVTALRM,
253: #endif
254: #ifdef SIGXFSZ
255: SIGXFSZ,
256: #endif
257: };
258: static short sigs_to_quit [] = {
259: #ifdef SIGHUP
260: SIGHUP,
261: #endif
262: #ifdef SIGQUIT
263: SIGQUIT,
264: #endif
265: #ifdef SIGABRT
266: SIGABRT,
267: #endif
268: #ifdef SIGTERM
269: SIGTERM,
270: #endif
271: #ifdef SIGXCPU
272: SIGXCPU,
273: #endif
274: };
275: int i;
276:
277: #define DIM(X) (sizeof (X) / sizeof *(X))
278: /*
279: for (i = 0; i < DIM (sigs_to_ignore); i++)
280: signal (sigs_to_ignore [i], SIG_IGN);
281: */
282: for (i = 0; i < DIM (sigs_to_throw); i++)
283: signal (sigs_to_throw [i], die_on_signal ? graceful_exit : signal_throw);
284: for (i = 0; i < DIM (sigs_to_quit); i++)
285: signal (sigs_to_quit [i], graceful_exit);
286: #ifdef SIGCONT
287: signal (SIGCONT, termprep);
288: #endif
289: #ifdef SIGWINCH
290: signal (SIGWINCH, change_winsize);
291: #endif
292: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>