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