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