Annotation of freem/src/sighnd.c, revision 1.7
1.1 snw 1: /*
1.7 ! snw 2: * $Id: sighnd.c,v 1.6 2025/03/24 04:15:25 snw Exp $
1.1 snw 3: * FreeM signal handlers
4: *
5: *
1.2 snw 6: * Author: Serena Willis <snw@coherent-logic.com>
1.1 snw 7: * Copyright (C) 1998 MUG Deutschland
1.3 snw 8: * Copyright (C) 2020, 2025 Coherent Logic Development LLC
1.1 snw 9: *
10: *
11: * This file is part of FreeM.
12: *
13: * FreeM is free software: you can redistribute it and/or modify
14: * it under the terms of the GNU Affero Public License as published by
15: * the Free Software Foundation, either version 3 of the License, or
16: * (at your option) any later version.
17: *
18: * FreeM is distributed in the hope that it will be useful,
19: * but WITHOUT ANY WARRANTY; without even the implied warranty of
20: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21: * GNU Affero Public License for more details.
22: *
23: * You should have received a copy of the GNU Affero Public License
24: * along with FreeM. If not, see <https://www.gnu.org/licenses/>.
25: *
1.4 snw 26: * $Log: sighnd.c,v $
1.7 ! snw 27: * Revision 1.6 2025/03/24 04:15:25 snw
! 28: * Create dummy onwinch signal handler for OS/2
! 29: *
1.6 snw 30: * Revision 1.5 2025/03/24 00:38:40 snw
31: * Fix termios junk in sighnd.c
32: *
1.5 snw 33: * Revision 1.4 2025/03/24 00:34:30 snw
34: * Fix termios junk in sighnd.c
35: *
1.4 snw 36: * Revision 1.3 2025/03/09 19:50:47 snw
37: * Second phase of REUSE compliance and header reformat
38: *
1.3 snw 39: *
40: * SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
41: * SPDX-License-Identifier: AGPL-3.0-or-later
1.1 snw 42: **/
43:
44: #include <stddef.h>
45: #include <stdlib.h>
46: #include <setjmp.h>
47: #include <signal.h>
48: #include <unistd.h>
49: #include <stdio.h>
50:
51: #include <sys/types.h>
52: #include <sys/wait.h>
53:
1.4 snw 54: #if !defined(__APPLE__) && !defined(__gnu_hurd__) && !defined(EMSCRIPTEN)
55: # if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__AMIGA)
56: # include <termios.h>
57: # if !defined(__AMIGA)
58: # define TCGETA TIOCGETA
59: # define TCSETA TIOCSETA
60: # endif
61: # define termio termios
62: # else
63: # if !defined(MSDOS)
64: # include <termio.h>
65: # endif
66: # endif
67: #else
68: # include <termios.h>
69: #endif
70:
1.1 snw 71: #include <sys/ioctl.h>
72:
73: #include "mpsdef.h"
74: #include "transact.h"
75: #include "init.h"
76: #include "events.h"
77: #include "jobtab.h"
78: #include "shmmgr.h"
79:
1.4 snw 80:
81:
1.1 snw 82: void m_log (int, const char *);
83: int pending_signal_type = -1;
84:
85: void sig_attach(int sig, void *handler)
86: {
87: struct sigaction act;
88:
89: act.sa_handler = handler;
90: #if !defined(__AMIGA)
91: sigaction (sig, &act, NULL);
92: #else
1.7 ! snw 93: /* TODO: fill in for m68k-amigaos */
1.1 snw 94: #endif
95: }
96:
97:
98: void sig_init(void)
99: {
100: /* signals stuff */
101: sig_attach (SIGINT, &onintr); /* set_up INTERRUPT */
102: sig_attach (SIGQUIT, &onquit); /* set_up ZBREAK */
103: sig_attach (SIGTERM, &onkill); /* catch kill signal */
104:
105: #if !defined(__CYGWIN__) && !defined(MSDOS)
106: sig_attach (SIGIOT, &onbus); /* catch IOT error */
107: #endif/*__CYGWIN__*/
108:
109: #ifndef LINUX
110: sig_attach (SIGEMT, &onbus); /* catch EMT error */
111: #endif/*LINUX*/
112:
113: #if !defined(MSDOS)
114: sig_attach (SIGWINCH, &onwinch);
115: #endif
116:
117: sig_attach (SIGUSR1, &oncld); /* catch son dies signal */
118: sig_attach (SIGHUP, &onhup); /* catch hangup */
119:
120: sig_attach (SIGUSR2, &onipc); /* catch IPC signal */
121: sig_attach (SIGFPE, &onfpe); /* catch floating pt except */
122: }
123:
124:
1.5 snw 125: #if !defined(MSDOS) && !defined(__OS2__)
1.1 snw 126: void onwinch (void)
127: {
128: struct winsize ws;
129:
130: /* restore handler */
131: sig_attach (SIGWINCH, &onwinch);
132:
133: ioctl (STDIN_FILENO, TIOCGWINSZ, &ws);
134:
135: n_lines = ws.ws_row;
136: n_columns = ws.ws_col;
137:
138: if (evt_async_enabled) {
139: pending_signal_type = SIGWINCH;
140: merr_raise (ASYNC);
141: }
142:
143: return;
144: }
1.6 snw 145: #else
146: void onwinch (void)
147: {
148: sig_attach (SIGWINCH, &onwinch);
149:
150: return;
151: }
1.1 snw 152: #endif
153:
154: void onintr (void)
155: {
156: sig_attach (SIGINT, &onintr); /* restore handler */
157:
1.7 ! snw 158: /* printf ("\r\nSIGINT codptr = '%s'\r\n", codptr); */
1.1 snw 159:
160: if (first_process) {
161: job_request_stop (pid);
162: }
163: else {
164: if (shm_config->hdr->maintenance_mode == 1) {
165:
166: job_slot_t *s = job_get (pid);
167:
168:
169: if ((s->flags & JFLG_FMADM) != JFLG_FMADM) {
170:
171: fprintf (stderr, "\r\n***ENVIRONMENT IN MAINTENANCE MODE***\r\n");
172:
173: while (shm_config->hdr->maintenance_mode == 1) {
174: sleep (1);
175: }
176:
177: return;
178:
179: }
180:
181: }
182: }
183:
184:
185: if (breakon) {
186: merr_raise (INRPT);
187: inrpt_after_async = TRUE;
188: if (forsw) sigint_in_for = TRUE;
189: }
190: else {
191: zcc = TRUE;
192: }
193:
194: if (evt_async_enabled) {
195: pending_signal_type = SIGINT;
196: }
197:
198: return;
199: } /* end of onintr */
200:
201: void onfpe (void)
202: {
203: sig_attach (SIGFPE, &onfpe); /* restore handler */
204:
205: if (evt_async_enabled) {
206: pending_signal_type = SIGFPE;
207: }
208:
209: merr_raise (MXNUM);
210: return;
211: } /* end of onfpe */
212:
213: void onquit (void)
214: {
215:
216: if (run_daemon == TRUE) {
217: job_request_stop (pid);
218: }
219:
220: sig_attach (SIGQUIT, &onquit); /* restore handler */
221:
222: if (zbreakon && (merr () == OK)) ierr = OK - CTRLB;
223:
224: if (evt_async_enabled) {
225: pending_signal_type = SIGQUIT;
226: }
227:
228: return;
229: } /* end of onquit */
230:
231: void onkill (void)
232: {
233: int n = 0;
234:
235: if (run_daemon == TRUE) {
236: job_request_stop (pid);
237: }
238:
239: #if !defined(AMIGA68K)
240: if (direct_mode == TRUE) {
241: set_io (UNIX);
242: fprintf (stderr, "\n\nFreeM process %d caught SIGTERM\n", pid);
243: set_io (MUMPS);
244: }
245: #endif
246:
247:
248: sig_attach (SIGTERM, &onkill); /* restore handler */
249:
250: if (killerflag == FALSE) return; /* ignore that signal */
251:
252: /* if there exists an error trap, process as an error */
253: /* otherwise terminate the job */
254:
255: if (DSM2err) { /* DSM V.2 error trapping */
256:
257:
258:
259: if (ztrap[NESTLEVLS + 1][0] != EOL) {
260: merr_raise (KILLER);
261: return;
262: }
263:
264:
265: }
266: else {
267:
268:
269: while (n >= 0) {
270: if (ztrap[n--][0] != EOL) {
271: merr_raise (KILLER);
272: return;
273: }
274: }
275:
276:
277: }
278:
279: cleanup ();
280: if (father) kill (father, SIGUSR1); /* advertise death to parent */
281:
282: exit (1); /* terminate mumps */
283: } /* end of onkill() */
284:
285: void onhup (void)
286: {
287:
288: int n = nstx;
289:
290:
291: if (run_daemon == TRUE) {
292: fprintf (stderr, "freem: daemon received SIGHUP\r\n");
293: m_log (1, "freem: daemon received SIGHUP");
294:
295: sig_attach (SIGHUP, &onhup); /* restore handler */
296:
297: return;
298: }
299:
300: sig_attach (SIGHUP, &onhup); /* restore handler */
301:
302: if (huperflag == FALSE) return; /* ignore that signal */
303:
304: /* if there exists an error trap, process as an error */
305: /* otherwise terminate the job */
306:
307: if (DSM2err) { /* DSM V.2 error trapping */
308:
309: if (ztrap[NESTLEVLS + 1][0] != EOL) {
310: merr_raise (HUPER);
311: return;
312: }
313:
314:
315: }
316: else {
317:
318: while (n >= 0) {
319: if (ztrap[n--][0] != EOL) {
320: merr_raise (HUPER);
321: return;
322: }
323: }
324:
325: }
326:
327: cleanup ();
328:
329: if (father) kill (father, SIGUSR1); /* advertise death to parent */
330:
331: exit (1); /* terminate mumps */
332:
333: } /* end of onhup() */
334:
335: void onbus (void)
336: {
337: cleanup ();
338:
339: printf ("\012\015BUS ERROR, SEGMENTATION VIOLATION\012\015");
340:
341: if (father) kill (father, SIGUSR1); /* advertise death to parent */
342:
343: exit (1); /* terminate mumps */
344: } /* end of onbus() */
345:
346: /* under XENIX processes started with JOB hang around as zombies */
347: /* if they HALT before the parent process, unless the parent process */
348: /* waits for his child to terminate. to solve the problem, the child */
349: /* sends a signal to his parent to avoid an unattended funeral which */
350: /* inevitably would result in a living dead sucking up cpu time */
351: void oncld (void)
352: {
353: int status;
354:
355: /* ignore signal while as we're here */
356: sig_attach (SIGUSR1, SIG_IGN);
357:
358: wait (&status); /* wait for report from child */
359:
360: sig_attach (SIGUSR1, &oncld);/* restore handler */
361:
362: return;
363: } /* end of oncld() */
364:
365: void onipc (void)
366: {
367: /* restore handler */
368: sig_attach (SIGUSR2, &onipc);
369:
370: ipc_pending = 1;
371:
372: return;
373: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>