Annotation of freem/src/sighnd.c, revision 1.11

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

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