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

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

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