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