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

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