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

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:  *  
1.2     ! snw        18:  *   Author: Serena Willis <snw@coherent-logic.com>
1.1       snw        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>