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>