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