File:  [Coherent Logic Development] / freem / src / sighnd.c
Revision 1.7: download - view: text, annotated - select for diffs
Thu Apr 10 01:24:38 2025 UTC (5 months, 2 weeks ago) by snw
Branches: MAIN
CVS tags: HEAD
Remove C++ style comments

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>