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