home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / LIBSRC.ZOO / libsrc / local / except.c < prev    next >
Text File  |  1992-04-04  |  16KB  |  500 lines

  1. #define INCL_DOSSIGNALS
  2. #define INCL_DOSMISC
  3. #include <os2.h>
  4. #include <signal.h>
  5. #include <stdio.h>
  6.  
  7. #define XSIGNAL(x) (XCPT_FATAL_EXCEPTION | XCPT_CUSTOMER_CODE | (x))
  8.  
  9. /* Signal mask for this process... initially none blocked */
  10.  
  11. int __signal_mask = 0;
  12.  
  13. /* List of actions.  One for each signal */
  14.  
  15. void *__signal_proc[32] = {SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
  16.                            SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
  17.                            SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
  18.                            SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
  19.                            SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
  20.                            SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
  21.                            SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL,
  22.                            SIG_DFL, SIG_DFL, SIG_DFL, SIG_DFL};
  23.  
  24. /* List of masks to be used when handler is running.  One for each signal */
  25. /* zero means block the signal being delivered and leave the rest of the mask as is */
  26.  
  27. int __handler_mask[32] = {0, 0, 0, 0, 0, 0, 0, 0,
  28.                           0, 0, 0, 0, 0, 0, 0, 0,
  29.                           0, 0, 0, 0, 0, 0, 0, 0,
  30.                           0, 0, 0, 0, 0, 0, 0, 0};
  31.  
  32. static int user_handler (int);
  33. static void GenReturnCode (int);
  34.  
  35. ULONG Dos32CreateThread() asm ("Dos32CreateThread");
  36. ULONG Dos32WaitThread() asm ("Dos32WaitThread");
  37. ULONG Dos32Exit() asm ("Dos32Exit");
  38. ULONG Dos32Error() asm ("Dos32Error");
  39.  
  40. __SignalHandler(EXCEPTIONREPORTRECORD *parg)
  41. {
  42.    switch (parg -> ExceptionNum)
  43.    {
  44.        /* SIGHUP */
  45.     case XSIGNAL(SIGHUP):
  46.        if (user_handler (SIGHUP) || __signal_proc[SIGHUP] == SIG_IGN)
  47.           return (XCPT_CONTINUE_EXECUTION);
  48.        else {
  49.           TID ThreadID;
  50.           Dos32CreateThread (&ThreadID,
  51.                              GenReturnCode,
  52.                              SIGHUP,
  53.                              0,
  54.                              4096);
  55.           Dos32WaitThread (&ThreadID, 0);
  56.           Dos32Error (FERR_DISABLEEXCEPTION);
  57.           return (XCPT_CONTINUE_SEARCH);
  58.        }
  59.  
  60.        /* SIGINT */
  61.     case XSIGNAL(SIGINT):
  62.     case XCPT_SIGNAL:  /* Also SIGTERM */
  63.        if (user_handler (SIGINT) || __signal_proc[SIGINT] == SIG_IGN)
  64.           return (XCPT_CONTINUE_EXECUTION);
  65.        else {
  66.           TID ThreadID;
  67.           Dos32CreateThread (&ThreadID,
  68.                              GenReturnCode,
  69.                              SIGINT,
  70.                              0,
  71.                              4096);
  72.           Dos32WaitThread (&ThreadID, 0);
  73.           if (parg -> ExceptionNum == XSIGNAL(SIGINT))
  74.              Dos32Error (FERR_DISABLEEXCEPTION);
  75.           return (XCPT_CONTINUE_SEARCH);
  76.        }
  77.  
  78.        /* SIGQUIT */
  79.     case XSIGNAL(SIGQUIT):
  80.        if (user_handler (SIGQUIT) || __signal_proc[SIGQUIT] == SIG_IGN)
  81.           return (XCPT_CONTINUE_EXECUTION);
  82.        else {
  83.           TID ThreadID;
  84.           Dos32CreateThread (&ThreadID,
  85.                              GenReturnCode,
  86.                              SIGQUIT,
  87.                              0,
  88.                              4096);
  89.           Dos32WaitThread (&ThreadID, 0);
  90.           Dos32Error (FERR_DISABLEEXCEPTION);
  91.           return (XCPT_CONTINUE_SEARCH);
  92.        }
  93.  
  94.        /* SIGILL */
  95.     case XSIGNAL(SIGILL):
  96.     case XCPT_ILLEGAL_INSTRUCTION:
  97.        if (user_handler (SIGILL) || __signal_proc[SIGILL] == SIG_IGN)
  98.           return (XCPT_CONTINUE_EXECUTION);
  99.        else {
  100.           TID ThreadID;
  101.           Dos32CreateThread (&ThreadID,
  102.                              GenReturnCode,
  103.                              SIGILL,
  104.                              0,
  105.                              4096);
  106.           Dos32WaitThread (&ThreadID, 0);
  107.           if (parg -> ExceptionNum == XSIGNAL(SIGILL))
  108.              Dos32Error (FERR_DISABLEEXCEPTION);
  109.           return (XCPT_CONTINUE_SEARCH);
  110.        }
  111.  
  112.        /* SIGTRAP */
  113.     case XSIGNAL(SIGTRAP):
  114.     case XCPT_BREAKPOINT:
  115.     case XCPT_SINGLE_STEP:
  116.        if (user_handler (SIGTRAP) || __signal_proc[SIGTRAP] == SIG_IGN)
  117.           return (XCPT_CONTINUE_EXECUTION);
  118.        else {
  119.           TID ThreadID;
  120.           Dos32CreateThread (&ThreadID,
  121.                              GenReturnCode,
  122.                              SIGTRAP,
  123.                              0,
  124.                              4096);
  125.           Dos32WaitThread (&ThreadID, 0);
  126.           if (parg -> ExceptionNum == XSIGNAL(SIGTRAP))
  127.              Dos32Error (FERR_DISABLEEXCEPTION);
  128.           return (XCPT_CONTINUE_SEARCH);
  129.        }
  130.  
  131.        /* SIGABRT */
  132.     case XSIGNAL(SIGABRT):
  133.        if (user_handler (SIGABRT) || __signal_proc[SIGABRT] == SIG_IGN)
  134.           return (XCPT_CONTINUE_EXECUTION);
  135.        else {
  136.           TID ThreadID;
  137.           fprintf (stderr, "\nabnormal program termination\n");
  138.           Dos32CreateThread (&ThreadID,
  139.                              GenReturnCode,
  140.                              SIGABRT,
  141.                              0,
  142.                              4096);
  143.           Dos32WaitThread (&ThreadID, 0);
  144.           Dos32Error (FERR_DISABLEEXCEPTION);
  145.           return (XCPT_CONTINUE_SEARCH);
  146.        }
  147.  
  148.        /* SIGEMT */
  149.     case XSIGNAL(SIGEMT):
  150.        if (user_handler (SIGEMT) || __signal_proc[SIGEMT] == SIG_IGN)
  151.           return (XCPT_CONTINUE_EXECUTION);
  152.        else {
  153.           TID ThreadID;
  154.           Dos32CreateThread (&ThreadID,
  155.                              GenReturnCode,
  156.                              SIGEMT,
  157.                              0,
  158.                              4096);
  159.           Dos32WaitThread (&ThreadID, 0);
  160.           Dos32Error (FERR_DISABLEEXCEPTION);
  161.           return (XCPT_CONTINUE_SEARCH);
  162.        }
  163.  
  164.        /* SIGFPE */
  165.     case XSIGNAL(SIGFPE):
  166.     case XCPT_FLOAT_DIVIDE_BY_ZERO:
  167.     case XCPT_FLOAT_INVALID_OPERATION:
  168.     case XCPT_FLOAT_OVERFLOW:
  169.     case XCPT_FLOAT_UNDERFLOW:
  170.     case XCPT_FLOAT_DENORMAL_OPERAND:
  171.     case XCPT_FLOAT_INEXACT_RESULT:
  172.     case XCPT_FLOAT_STACK_CHECK:
  173.     case XCPT_INTEGER_DIVIDE_BY_ZERO:
  174.        if (user_handler (SIGFPE) || __signal_proc[SIGFPE] == SIG_IGN)
  175.           return (XCPT_CONTINUE_EXECUTION);
  176.        else {
  177.           TID ThreadID;
  178.           Dos32CreateThread (&ThreadID,
  179.                              GenReturnCode,
  180.                              SIGFPE,
  181.                              0,
  182.                              4096);
  183.           Dos32WaitThread (&ThreadID, 0);
  184.           if (parg -> ExceptionNum == XSIGNAL(SIGFPE))
  185.              Dos32Error (FERR_DISABLEEXCEPTION);
  186.           return (XCPT_CONTINUE_SEARCH);
  187.        }
  188.  
  189.        /* SIGKILL */
  190.     case XSIGNAL(SIGKILL):
  191.        Dos32Error (FERR_DISABLEEXCEPTION);
  192.        return (XCPT_CONTINUE_SEARCH);
  193.  
  194.        /* SIGBUS */
  195.     case XSIGNAL(SIGBUS):
  196.        if (user_handler (SIGBUS) || __signal_proc[SIGBUS] == SIG_IGN)
  197.           return (XCPT_CONTINUE_EXECUTION);
  198.        else {
  199.           TID ThreadID;
  200.           Dos32CreateThread (&ThreadID,
  201.                              GenReturnCode,
  202.                              SIGBUS,
  203.                              0,
  204.                              4096);
  205.           Dos32WaitThread (&ThreadID, 0);
  206.           Dos32Error (FERR_DISABLEEXCEPTION);
  207.           return (XCPT_CONTINUE_SEARCH);
  208.        }
  209.  
  210.        /* SIGSEGV */
  211.     case XSIGNAL(SIGSEGV):
  212.     case XCPT_ACCESS_VIOLATION:
  213.        if (user_handler (SIGSEGV) || __signal_proc[SIGSEGV] == SIG_IGN)
  214.           return (XCPT_CONTINUE_EXECUTION);
  215.        else {
  216.           TID ThreadID;
  217.           Dos32CreateThread (&ThreadID,
  218.                              GenReturnCode,
  219.                              SIGSEGV,
  220.                              0,
  221.                              4096);
  222.           Dos32WaitThread (&ThreadID, 0);
  223.           if (parg -> ExceptionNum == XSIGNAL(SIGSEGV))
  224.              Dos32Error (FERR_DISABLEEXCEPTION);
  225.           return (XCPT_CONTINUE_SEARCH);
  226.        }
  227.  
  228.        /* SIGSYS */
  229.     case XSIGNAL(SIGSYS):
  230.     case XCPT_BAD_STACK:
  231.     case XCPT_INVALID_UNWIND_TARGET:
  232.        if (user_handler (SIGSYS) || __signal_proc[SIGSYS] == SIG_IGN)
  233.           return (XCPT_CONTINUE_EXECUTION);
  234.        else {
  235.           TID ThreadID;
  236.           Dos32CreateThread (&ThreadID,
  237.                              GenReturnCode,
  238.                              SIGSYS,
  239.                              0,
  240.                              4096);
  241.           Dos32WaitThread (&ThreadID, 0);
  242.           if (parg -> ExceptionNum == XSIGNAL(SIGSYS))
  243.              Dos32Error (FERR_DISABLEEXCEPTION);
  244.           return (XCPT_CONTINUE_SEARCH);
  245.        }
  246.  
  247.        /* SIGPIPE */
  248.     case XSIGNAL(SIGPIPE):
  249.        if (user_handler (SIGPIPE) || __signal_proc[SIGPIPE] == SIG_IGN)
  250.           return (XCPT_CONTINUE_EXECUTION);
  251.        else {
  252.           TID ThreadID;
  253.           Dos32CreateThread (&ThreadID,
  254.                              GenReturnCode,
  255.                              SIGPIPE,
  256.                              0,
  257.                              4096);
  258.           Dos32WaitThread (&ThreadID, 0);
  259.           Dos32Error (FERR_DISABLEEXCEPTION);
  260.           return (XCPT_CONTINUE_SEARCH);
  261.        }
  262.  
  263.        /* SIGALRM */
  264.     case XSIGNAL(SIGALRM):
  265.        if (user_handler (SIGALRM) || __signal_proc[SIGALRM] == SIG_IGN)
  266.           return (XCPT_CONTINUE_EXECUTION);
  267.        else {
  268.           TID ThreadID;
  269.           Dos32CreateThread (&ThreadID,
  270.                              GenReturnCode,
  271.                              SIGALRM,
  272.                              0,
  273.                              4096);
  274.           Dos32WaitThread (&ThreadID, 0);
  275.           Dos32Error (FERR_DISABLEEXCEPTION);
  276.           return (XCPT_CONTINUE_SEARCH);
  277.        }
  278.  
  279.        /* SIGTERM */
  280.     case XSIGNAL(SIGTERM):
  281.        Dos32Error (FERR_DISABLEEXCEPTION);
  282.        return (XCPT_CONTINUE_SEARCH);
  283.  
  284.        /* SIGURG */
  285.     case XSIGNAL(SIGURG):
  286.        user_handler (SIGURG);
  287.        return (XCPT_CONTINUE_EXECUTION);
  288.  
  289.        /* SIGSTOP */
  290.     case XSIGNAL(SIGSTOP):
  291.        Dos32Error (FERR_DISABLEEXCEPTION);
  292.        return (XCPT_CONTINUE_SEARCH);
  293.  
  294.        /* SIGTSTP */
  295.     case XSIGNAL(SIGTSTP):
  296.        if (user_handler (SIGTSTP) || __signal_proc[SIGTSTP] == SIG_IGN)
  297.           return (XCPT_CONTINUE_EXECUTION);
  298.        else {
  299.           TID ThreadID;
  300.           Dos32CreateThread (&ThreadID,
  301.                              GenReturnCode,
  302.                              SIGTSTP,
  303.                              0,
  304.                              4096);
  305.           Dos32WaitThread (&ThreadID, 0);
  306.           Dos32Error (FERR_DISABLEEXCEPTION);
  307.           return (XCPT_CONTINUE_SEARCH);
  308.        }
  309.  
  310.        /* SIGCONT */
  311.     case XSIGNAL(SIGCONT):
  312.        user_handler (SIGCONT);
  313.        return (XCPT_CONTINUE_EXECUTION);
  314.  
  315.        /* SIGCHLD */
  316.     case XSIGNAL(SIGCHLD):
  317.        user_handler (SIGCHLD);
  318.        return (XCPT_CONTINUE_EXECUTION);
  319.  
  320.        /* SIGTTIN */
  321.     case XSIGNAL(SIGTTIN):
  322.        if (user_handler (SIGTTIN) || __signal_proc[SIGTTIN] == SIG_IGN)
  323.           return (XCPT_CONTINUE_EXECUTION);
  324.        else {
  325.           TID ThreadID;
  326.           Dos32CreateThread (&ThreadID,
  327.                              GenReturnCode,
  328.                              SIGTTIN,
  329.                              0,
  330.                              4096);
  331.           Dos32WaitThread (&ThreadID, 0);
  332.           Dos32Error (FERR_DISABLEEXCEPTION);
  333.           return (XCPT_CONTINUE_SEARCH);
  334.        }
  335.  
  336.        /* SIGTTOU */
  337.     case XSIGNAL(SIGTTOU):
  338.        if (user_handler (SIGTTOU) || __signal_proc[SIGTTOU] == SIG_IGN)
  339.           return (XCPT_CONTINUE_EXECUTION);
  340.        else {
  341.           TID ThreadID;
  342.           Dos32CreateThread (&ThreadID,
  343.                              GenReturnCode,
  344.                              SIGTTOU,
  345.                              0,
  346.                              4096);
  347.           Dos32WaitThread (&ThreadID, 0);
  348.           Dos32Error (FERR_DISABLEEXCEPTION);
  349.           return (XCPT_CONTINUE_SEARCH);
  350.        }
  351.  
  352.        /* SIGIO */
  353.     case XSIGNAL(SIGIO):
  354.        user_handler (SIGIO);
  355.        return (XCPT_CONTINUE_EXECUTION);
  356.  
  357.        /* SIGXCPU */
  358.     case XSIGNAL(SIGXCPU):
  359.        if (user_handler (SIGXCPU) || __signal_proc[SIGXCPU] == SIG_IGN)
  360.           return (XCPT_CONTINUE_EXECUTION);
  361.        else {
  362.           TID ThreadID;
  363.           Dos32CreateThread (&ThreadID,
  364.                              GenReturnCode,
  365.                              SIGXCPU,
  366.                              0,
  367.                              4096);
  368.           Dos32WaitThread (&ThreadID, 0);
  369.           Dos32Error (FERR_DISABLEEXCEPTION);
  370.           return (XCPT_CONTINUE_SEARCH);
  371.        }
  372.  
  373.        /* SIGXFSZ */
  374.     case XSIGNAL(SIGXFSZ):
  375.        if (user_handler (SIGXFSZ) || __signal_proc[SIGXFSZ] == SIG_IGN)
  376.           return (XCPT_CONTINUE_EXECUTION);
  377.        else {
  378.           TID ThreadID;
  379.           Dos32CreateThread (&ThreadID,
  380.                              GenReturnCode,
  381.                              SIGXFSZ,
  382.                              0,
  383.                              4096);
  384.           Dos32WaitThread (&ThreadID, 0);
  385.           Dos32Error (FERR_DISABLEEXCEPTION);
  386.           return (XCPT_CONTINUE_SEARCH);
  387.        }
  388.  
  389.        /* SIGVTALRM */
  390.     case XSIGNAL(SIGVTALRM):
  391.        if (user_handler (SIGVTALRM) || __signal_proc[SIGVTALRM] == SIG_IGN)
  392.           return (XCPT_CONTINUE_EXECUTION);
  393.        else {
  394.           TID ThreadID;
  395.           Dos32CreateThread (&ThreadID,
  396.                              GenReturnCode,
  397.                              SIGVTALRM,
  398.                              0,
  399.                              4096);
  400.           Dos32WaitThread (&ThreadID, 0);
  401.           Dos32Error (FERR_DISABLEEXCEPTION);
  402.           return (XCPT_CONTINUE_SEARCH);
  403.        }
  404.  
  405.        /* SIGPROF */
  406.     case XSIGNAL(SIGPROF):
  407.        if (user_handler (SIGPROF) || __signal_proc[SIGPROF] == SIG_IGN)
  408.           return (XCPT_CONTINUE_EXECUTION);
  409.        else {
  410.           TID ThreadID;
  411.           Dos32CreateThread (&ThreadID,
  412.                              GenReturnCode,
  413.                              SIGPROF,
  414.                              0,
  415.                              4096);
  416.           Dos32WaitThread (&ThreadID, 0);
  417.           Dos32Error (FERR_DISABLEEXCEPTION);
  418.           return (XCPT_CONTINUE_SEARCH);
  419.        }
  420.  
  421.        /* SIGWINCH */
  422.     case XSIGNAL(SIGWINCH):
  423.        user_handler (SIGWINCH);
  424.        return (XCPT_CONTINUE_EXECUTION);
  425.  
  426.        /* SIGINFO */
  427.     case XSIGNAL(SIGINFO):
  428.        user_handler (SIGINFO);
  429.        return (XCPT_CONTINUE_EXECUTION);
  430.  
  431.        /* SIGUSR1 */
  432.     case XSIGNAL(SIGUSR1):
  433.        if (user_handler (SIGUSR1) || __signal_proc[SIGUSR1] == SIG_IGN)
  434.           return (XCPT_CONTINUE_EXECUTION);
  435.        else {
  436.           TID ThreadID;
  437.           Dos32CreateThread (&ThreadID,
  438.                              GenReturnCode,
  439.                              SIGUSR1,
  440.                              0,
  441.                              4096);
  442.           Dos32WaitThread (&ThreadID, 0);
  443.           Dos32Error (FERR_DISABLEEXCEPTION);
  444.           return (XCPT_CONTINUE_SEARCH);
  445.        }
  446.  
  447.        /* SIGUSR2 */
  448.     case XSIGNAL(SIGUSR2):
  449.        if (user_handler (SIGUSR2) || __signal_proc[SIGUSR2] == SIG_IGN)
  450.           return (XCPT_CONTINUE_EXECUTION);
  451.        else {
  452.           TID ThreadID;
  453.           Dos32CreateThread (&ThreadID,
  454.                              GenReturnCode,
  455.                              SIGUSR2,
  456.                              0,
  457.                              4096);
  458.           Dos32WaitThread (&ThreadID, 0);
  459.           Dos32Error (FERR_DISABLEEXCEPTION);
  460.           return (XCPT_CONTINUE_SEARCH);
  461.        }
  462.  
  463.  
  464.     case XCPT_GUARD_PAGE_VIOLATION:
  465.     case XCPT_UNABLE_TO_GROW_STACK:
  466.     case XCPT_PRIVILEGED_INSTRUCTION:
  467.     case XCPT_INTEGER_OVERFLOW:
  468.     case XCPT_DATATYPE_MISALIGNMENT:
  469.     case XCPT_IN_PAGE_ERROR:
  470.     case XCPT_NONCONTINUABLE_EXCEPTION:
  471.     case XCPT_INVALID_DISPOSITION:
  472.     case XCPT_INVALID_LOCK_SEQUENCE:
  473.     case XCPT_PROCESS_TERMINATE:
  474.     case XCPT_ASYNC_PROCESS_TERMINATE:
  475.     case XCPT_ARRAY_BOUNDS_EXCEEDED:
  476.     case XCPT_UNWIND:
  477.     default: 
  478.         return (XCPT_CONTINUE_SEARCH);
  479.  
  480.    }
  481. }
  482.  
  483. static int user_handler(int sig)
  484. {
  485.    void (*proc)(int);
  486.  
  487.    if (__signal_proc[sig] == SIG_DFL || __signal_proc[sig] == SIG_IGN)
  488.       return (0);
  489.  
  490.    proc = __signal_proc[sig];
  491.    proc(sig);
  492.    return (1);
  493. }
  494.  
  495. static void GenReturnCode (int code)
  496. {
  497.    Dos32Exit (0, code);
  498. }
  499.  
  500.