home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 1.ddi / WINLBSRC.ZIP / SIGNAL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  22.9 KB  |  609 lines

  1. /*----------------------------------------------------------------------*
  2.  * filename - signal.c                                                  *
  3.  *                                                                      *
  4.  * function(s) signal(), raise()                                        *
  5.  * usage                                                                *
  6.  *              Function prototypes are in SIGNAL.H                     *
  7.  *                                                                      *
  8.  *      oldcatcher = signal(sig, newcatcher);                           *
  9.  *              void (*oldcatcher)(int) Ptr to previous signal catcher  *
  10.  *              int  sig                Signal # to install catcher for *
  11.  *      void (*newcatcher)(int) Address of new signal catcher           *
  12.  *                                                                      *
  13.  *      rc = raise(sig);                                                *
  14.  *      int  rc                 Return code, success=0, error=!0        *
  15.  *      int  sig                Signal number to raise                  *
  16.  *----------------------------------------------------------------------*/
  17.  
  18. /*
  19.  *      C/C++ Run Time Library - Version 5.0
  20.  *
  21.  *      Copyright (c) 1987, 1992 by Borland International
  22.  *      All Rights Reserved.
  23.  *
  24.  */
  25.  
  26. #include <process.h>    /* Get definition for _exit() */
  27. #include <errno.h>
  28. #include <dos.h>
  29. #include <float.h>      /* Get definition for FPE_nn SEGV_nn ILL_nn types */
  30. #include <string.h>
  31. #include <signal.h>
  32.  
  33. #if defined( _Windows )
  34. #include <_win.h>
  35. #endif
  36.  
  37. #pragma warn -pro
  38.  
  39. #undef ANSI_CONFORMING
  40. #undef BOUNDS_TRAP
  41. #undef ILLEGALOP_TRAP
  42.  
  43. #define ANSI_CONFORMING
  44. #define BOUNDS_TRAP
  45. #define ILLEGALOP_TRAP
  46.  
  47. /*----------------------------- NOTE ! ---------------------------------
  48.  
  49. Normal ANSI operation resets ALL signals,  Microsoft(R) doesn't reset SIGFPE.
  50. Remove ANSI_CONFORMING define for MS style SIGFPE operation.
  51. Remove BOUNDS_TRAP define disables SIGSEGV bound violations.
  52. Remove ILLEGALOP_TRAP define disables SIGILL illegal op violations.
  53. Default configuration is ANSI conforming SIGFPE operation.
  54. Default configuration enables SIGSEGV to detect BOUND violations.
  55. Default configuration enables SIGSILL to detect illegal operations.
  56.  
  57.   ----------------------------- NOTE ! -------------------------------*/
  58.  
  59. typedef unsigned char UCHAR;
  60.  
  61. #if defined( _Windows )
  62.  
  63. #include <windows.h>
  64.  
  65. extern void (far *_FPVector)();
  66.  
  67. #else   // not _Windows
  68.  
  69. static void interrupt Int0Catcher(unsigned);
  70. static void interrupt Int4Catcher(unsigned);
  71.  
  72. #ifdef BOUNDS_TRAP
  73. typedef unsigned U;
  74.  
  75. static void interrupt (*BiosPrtScr)();  /* Old BIOS Int 5 vector */
  76.  
  77. static char GotInt5 = 0;
  78. static void interrupt Int5Catcher(U, U, U, U, U, U, U, U, U, U, U, U);
  79. #endif
  80.  
  81. #ifdef ILLEGALOP_TRAP
  82. static void interrupt Int6Catcher(unsigned);
  83. #endif
  84.  
  85. static void interrupt Int23Catcher(void);
  86. static int GetIndex(int);
  87.  
  88. #endif  // _Windows
  89.  
  90. _CatcherPTR _FARFUNC signal(int, _CatcherPTR);
  91. int _FARFUNC raise(int);
  92.  
  93. #if !defined( _Windows )
  94. extern  _CatcherPTR      (*__SignalPtr)();
  95. static  char            SignalPtrSet=0;
  96. #endif
  97.  
  98. #define BogusSignal     -1      /* Flags a bogus signal type    */
  99.  
  100. /*+----------------------------------------------------------------------+
  101.   |       Signal Dispatch, Index Generator & Signal Default Tables       |
  102.   | *** Note : Ordering of constants in these tables MUST match          |
  103.   +----------------------------------------------------------------------+*/
  104. #define SIGINT_INDEX    0
  105. #define SIGILL_INDEX    1
  106. #define SIGFPE_INDEX    2
  107. #define SIGSEGV_INDEX   3
  108. #define SIGTERM_INDEX   4
  109. #define SIGABRT_INDEX   5
  110.  
  111. static _CatcherPTR Dispatch[] =
  112. {
  113.         (_CatcherPTR)SIG_DFL,    /* SIGINT   (2) */
  114.         (_CatcherPTR)SIG_DFL,    /* SIGILL   (4) */
  115.         (_CatcherPTR)SIG_DFL,    /* SIGFPE   (8) */
  116.         (_CatcherPTR)SIG_DFL,    /* SIGSEGV  (11)*/
  117.         (_CatcherPTR)SIG_DFL,    /* SIGTERM  (15)*/
  118.         (_CatcherPTR)SIG_DFL     /* SIGABRT  (22)*/
  119. };
  120.  
  121. #ifdef _BUILDRTLDLL
  122. static unsigned SavedDS[6] =
  123. {
  124.         0,                      /* SIGINT  */
  125.         0,                      /* SIGILL  */
  126.         0,                      /* SIGFPE  */
  127.         0,                      /* SIGSEGV */
  128.         0,                      /* SIGTERM */
  129.         0                       /* SIGABRT */
  130. };
  131. #endif
  132.  
  133. static const UCHAR IxGen[] =
  134. {
  135. /* NEVER! change the ordering of these */
  136.  
  137.         SIGINT,                 /* Index 0 */
  138.         SIGILL,                 /* Index 1 */
  139.         SIGFPE,                 /* Index 2 */
  140.         SIGSEGV,                /* Index 3 */
  141.         SIGTERM,                /* Index 4 */
  142.         SIGABRT                 /* Index 5 */
  143. };
  144.  
  145. /*+----------------------------------------------------------------------+
  146.   |            Table of values for EXPLICITLY raised signals             |
  147.   |  For SIGILL, SIGFPE & SIGSEGV explicit generation may have special   |
  148.   |  meaning to applications.  For the others use dummy 0's.             |
  149.   +----------------------------------------------------------------------+*/
  150. static const UCHAR ExplicitVal[] =
  151. {
  152.         0,                      /* SIGINT  */
  153.         ILL_EXPLICITGEN,        /* SIGILL  */
  154.         FPE_EXPLICITGEN,        /* SIGFPE  */
  155.         SEGV_EXPLICITGEN,       /* SIGSEGV */
  156.         0,                      /* SIGTERM */
  157.         0                       /* SIGABRT */
  158. };
  159.  
  160.  
  161. #if !defined( _Windows )
  162.  
  163. #ifdef BOUNDS_TRAP
  164. /*+----------------------------------------------------------------------+
  165.   |  Int5Catcher() - Int 5 catcher for detecting BOUND violations on     |
  166.   |                  80188/80186/80286/80386 & NEC V Series processors.  |
  167.   |                                                                      |
  168.   |  This routine is installed when any call to signal with SIGSEGV is   |
  169.   |  specified.  THIS ROUTINE REMAINS INSTALLED AS THE INT 5 HANDLER FOR |
  170.   |  THE REST OF THE PROGRAM DURATION.                                   |
  171.   |  When activated this routine checks where the interrupt came from.   |
  172.   |  If the return CS:IP points to a BOUND instruction it is assumed the |
  173.   |  bounds check done by that instruction failed.  If the return CS:IP  |
  174.   |  points to something other than a BOUND instruction then we assume   |
  175.   |  that the user wanted to do a BIOS Prt-screen.  We call the old BIOS |
  176.   |  handler in this case.                                               |
  177.   |                                                                      |
  178.   +----------------------------------------------------------------------+
  179.   |                                                                      |
  180.   |  There are some EXTREMELY rare cases where this scheme fails.        |
  181.   |  One is when somebody does the following instruction sequence in     |
  182.   |  their code (which I doubt has EVER been done ANYWHERE by anybody):  |
  183.   |                                                                      |
  184.   |               INT 5           ; Do a prt-screen                      |
  185.   |               BOUND  ...      ; Check bounds                         |
  186.   |                                                                      |
  187.   |  Here the return CS:IP on the interrupt handlers stack DOES point to |
  188.   |  a BOUND instruction, but one that hasn't been executed yet!  We     |
  189.   |  might think the heuristic "if it's a BOUND instruction proceeded by |
  190.   |  an INT 5 then it's not a REAL violation." would serve us well here, |
  191.   |  but alas it doesn't because the following situation can exist.      |
  192.   |  A program jumps to a BOUND instruction that is preceded by some     |
  193.   |  DATA that happens to LOOK like an INT 5 instruction by accident ex: |
  194.   |                                                                      |
  195.   |              JMP   DOBOUND                                           |
  196.   |  SOMEDATA    DB    0CDH, 5   ; Data that looks like an INT 5         |
  197.   |  DOBOUND :   BOUND  ...      ; Check bounds                          |
  198.   |                                                                      |
  199.   |  In the above example the heuristic fails us completely.             |
  200.   |                                                                      |
  201.   |  Thus, we're left solidly impaled on the horns of a dilemma.  Do we  |
  202.   |  recognize a BOUND violation where none exists, or do we ignore a    |
  203.   |  possibly genuine BOUND violation?  Hmm... if only Prt-Scr wasn't on |
  204.   |  INT 5.                                                              |
  205.   |                                                                      |
  206.   |  So... what do we do here, eh?                                       |
  207.   |  For the sake of expedience we'll punt.  A quick look at the         |
  208.   |  instruction pointed to by the return CS:IP will be done. If we      |
  209.   |  see a BOUND instruction we call the handler.                        |
  210.   |                                                                      |
  211.   |  Avoiding these situations amounts to putting a NOP before           |
  212.   |  any BOUND instruction that is in one of these rare situations.      |
  213.   |  Not exactly a tough a work around!                                  |
  214.   +----------------------------------------------------------------------+*/
  215.  
  216. #pragma argsused
  217. static void interrupt Int5Catcher(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags)
  218. unsigned bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags;
  219. {
  220.         register _CatcherPTR     action;
  221.  
  222. #define BND_OPCODE      0x62
  223.  
  224.         if (*(*((UCHAR far * far *)((unsigned far *)&ip))) != BND_OPCODE)
  225.                 (*BiosPrtScr)();                     // Hand off Prt-Sc request
  226.         else                                         // Process BOUND violation
  227.                 if ((action = Dispatch[3]) != SIG_IGN)
  228.                 {
  229.                         if ((action == SIG_DFL) || (action == SIG_ERR))
  230.                                 _exit(1);
  231.                         Dispatch[3] = SIG_DFL;        // Reset signal
  232.                         (*action)(SIGSEGV, SEGV_BOUND, &bp); // Call handler
  233.                 }
  234. }
  235. #endif  /*** BOUNDS_TRAP ***/
  236.  
  237. #ifdef ILLEGALOP_TRAP
  238. /*+----------------------------------------------------------------------+
  239.   |  Int6Catcher() - Int 6 catcher for detecting illegal operations on   |
  240.   |                  80188/80186/80286/80386 & NEC V Series processors.  |
  241.   |                                                                      |
  242.   |  This routine is installed when any call to signal with SIGILL is    |
  243.   |  specified.  THIS ROUTINE REMAINS INSTALLED AS THE INT 6 HANDLER FOR |
  244.   |  THE REST OF THE PROGRAM DURATION.                                   |
  245.   +----------------------------------------------------------------------+*/
  246. static void interrupt Int6Catcher(bp)
  247. unsigned bp;
  248. {
  249.         register _CatcherPTR     action;
  250.  
  251.         if ((action = Dispatch[1]) != SIG_IGN)
  252.         {
  253.                 if ((action == SIG_DFL) || (action == SIG_ERR))
  254.                         _exit(1);
  255.                 Dispatch[1] = SIG_DFL;          /* Reset signal */
  256.                 (*action)(SIGILL, ILL_EXECUTION, &bp);  /* Call handler */
  257.         }
  258. }
  259. #endif  /*** ILLEGALOP_TRAP ***/
  260.  
  261. /*+----------------------------------------------------------------------+
  262.   |  Int0Catcher() - Integer divide by zero exception handler.           |
  263.   |                  This routine is part of the extensions to SIGFPE    |
  264.   |                  handling to include integer arithmetic exceptions.  |
  265.   |                  ANSI doesn't restrict SIGFPE to just floats!        |
  266.   |                                                                      |
  267.   |  This routine is installed when any call to signal with SIGFPE is    |
  268.   |  specified.  When activated this routine does the equivalent of      |
  269.   |  raise(SIGFPE, ...).  THIS ROUTINE REMAINS INSTALLED AS THE DIVIDE   |
  270.   |  BY ZERO HANDLER FOR THE REST OF THE PROGRAM DURATION.  If the       |
  271.   |  application never installs a SIGFPE handler then the default action |
  272.   |  setup by the 'C' startup code will be used.  If the app steals      |
  273.   |  INT 0 back from us the only way the INT 0 SIGFPE code can be        |
  274.   |  reactivated is signal(SIGFPE, ....) again!                          |
  275.   +----------------------------------------------------------------------+*/
  276. static void interrupt Int0Catcher(bp)
  277. unsigned bp;
  278. {
  279.         register _CatcherPTR     action;
  280.  
  281.         if ((action = Dispatch[2]) != SIG_IGN)
  282.         {
  283.                 if ((action == SIG_DFL) || (action == SIG_ERR))
  284.                         _exit(1);
  285. #ifdef ANSI_CONFORMING
  286.                 Dispatch[2] = SIG_DFL;          /* Reset signal */
  287. #endif
  288.                 (*action)(SIGFPE, FPE_INTDIV0, &bp);    /* Call handler */
  289.         }
  290. }
  291.  
  292. /*+----------------------------------------------------------------------+
  293.   |  Int4Catcher() - Interrupt on overflow handler.                      |
  294.   |                  This routine is part of the extensions to SIGFPE    |
  295.   |                  handling to include integer arithmetic exceptions.  |
  296.   |                  ANSI doesn't restrict SIGFPE to just floats!        |
  297.   |                                                                      |
  298.   |  This routine is installed when any call to signal with SIGFPE is    |
  299.   |  specified.  When activated this routine does the equivalent of      |
  300.   |  raise(SIGFPE, ...).  THIS ROUTINE REMAINS INSTALLED AS THE Int 4    |
  301.   |  HANDLER FOR THE REST OF THE PROGRAM DURATION.  If the               |
  302.   |  application never installs a SIGFPE handler then the default actions|
  303.   |  apply. If the app steals INT 4 back from us the only way the INT 4  |
  304.   |  SIGFPE code can be reactivated is call signal(SIGFPE, ....) again!  |
  305.   +----------------------------------------------------------------------+*/
  306. static void interrupt Int4Catcher(bp)
  307. unsigned bp;
  308. {
  309.         register _CatcherPTR     action;
  310.  
  311.         if ((action = Dispatch[2]) != SIG_IGN)
  312.         {
  313.                 if ((action == SIG_DFL) || (action == SIG_ERR))
  314.                         _exit(1);
  315. #ifdef ANSI_CONFORMING
  316.                 Dispatch[2] = SIG_DFL;          /* Reset signal */
  317. #endif
  318.                 (*action)(SIGFPE, FPE_INTOVFLOW, &bp);  /* Call handler */
  319.         }
  320. }
  321.  
  322. /*+----------------------------------------------------------------------+
  323.   |          Routine intercepts int 23H and routes to user handler       |
  324.   +----------------------------------------------------------------------+*/
  325. static void interrupt Int23Catcher()
  326. {
  327.         register _CatcherPTR     action;
  328.  
  329.         if ((action = Dispatch[0]) != SIG_IGN)
  330.         {
  331.                 if ((action == SIG_DFL) || (action == SIG_ERR))
  332.                         _exit(1);
  333.                 Dispatch[0] = SIG_DFL;                  /* Reset signal */
  334.                 (*action)(SIGINT);                      /* Call handler */
  335.         }
  336. }
  337.  
  338. #endif  // !_Windows
  339.  
  340.  
  341. /*+----------------------------------------------------------------------+
  342.   |   GetIndex()  Get a DispatchTable index for specified signal type    |
  343.   +----------------------------------------------------------------------+*/
  344. static int GetIndex(int SigType)
  345. {
  346.         register int i;
  347.  
  348.         for (i = 0; i < sizeof(IxGen); i++)
  349.                 if (IxGen[i] == SigType)
  350.                         return i;
  351.         return -1;
  352. }
  353.  
  354. #ifdef _Windows
  355.  
  356. extern void far _fperr( void );
  357.  
  358. #endif
  359.  
  360. /*+----------------------------------------------------------------------+
  361.   |                Signal() - Install new signal catchers                |
  362.   +----------------------------------------------------------------------+*/
  363. _CatcherPTR _Cdecl _FARFUNC signal( int sig, _CatcherPTR New )
  364. //void _Cdecl _FARFUNC (* _Cdecl _FARFUNC signal( int sig, _CatcherPTR New))(int)
  365. {
  366.         register int    Index;
  367.         _CatcherPTR      OldVal;
  368. #if !defined( _Windows )
  369.         if (!SignalPtrSet)      /* let _fperr() know where signal is */
  370.         {
  371.                 __SignalPtr = signal;
  372.                 SignalPtrSet = 1;
  373.         }
  374. #endif  // __SignalPtr not used under Windows
  375.         /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  376.              Get an index for the signal type, if its bad exit.
  377.         - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  378.         if ((Index = GetIndex(sig)) == BogusSignal)
  379.         {
  380.                 errno = EINVAL;         /* Bogus 'sig' parm was passed  */
  381.                 return SIG_ERR;
  382.         }
  383.  
  384.         /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  385.         Install handler (SIGINT, SIGFPE & SIGSEGV are special)
  386.         - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  387.         OldVal = Dispatch[Index];               /* Save the OLD handler */
  388.         Dispatch[Index] = New;          /* Set the NEW handler  */
  389. #ifdef _BUILDRTLDLL
  390.         SavedDS[Index] = _SS;
  391. #endif
  392.  
  393. #if !defined( _Windows )
  394.         if (sig == SIGINT)
  395.         {
  396.                 setvect(0x23, Int23Catcher); /* Take INT 23H */
  397.         }
  398.         else if (sig == SIGFPE)
  399.         {
  400.                 setvect(0, Int0Catcher);     /* Take INT 0  */
  401.                 setvect(4, Int4Catcher);     /* Take INT 4  */
  402.         }
  403. #ifdef BOUNDS_TRAP
  404.         else if (sig == SIGSEGV)
  405.                 if (!GotInt5)
  406.                 {
  407.                         BiosPrtScr = getvect(5); /* Save old INT 5  */
  408.                         setvect(5, Int5Catcher); /* Take INT 5      */
  409.                         GotInt5 = 1;
  410.                 } else;
  411. #endif
  412. #ifdef ILLEGALOP_TRAP
  413.         else  if (sig == SIGILL)
  414.         {
  415.                 setvect(6, Int6Catcher); /* Take INT 6  */
  416.         }
  417. #endif
  418.  
  419. #endif  // !_Windows
  420.  
  421.         return OldVal;
  422. }
  423.  
  424. /*+----------------------------------------------------------------------+
  425.   |                raise() - generate a software 'event'                 |
  426.   +----------------------------------------------------------------------+*/
  427.  
  428. #if !defined( _Windows )
  429.  
  430. static void default_action( int SigType )
  431. {
  432.         switch (SigType)
  433.         {
  434.         case SIGABRT    :
  435.                 _exit(3);
  436.         case SIGINT     :
  437.                 geninterrupt( 0x23 );
  438.                 break;
  439.         case SIGILL     :
  440.         case SIGSEGV    :
  441.         case SIGTERM    :
  442.         case SIGFPE     :
  443.         default         :
  444.                 _exit(1);
  445.         }
  446. }
  447.  
  448. #else
  449.  
  450. #define FPE_DENORMAL        0x82
  451.  
  452. #define FPE_UNEMULATED      0x87
  453. #define FPE_SQRTNEG         0x88
  454. #define FPE_STACKOVERFLOW   0x8a
  455. #define FPE_STACKUNDERFLOW  0x8b
  456.  
  457. #undef  FPE_EXPLICITGEN
  458. #define FPE_EXPLICITGEN     0x8c    /* raise( SIGFPE ); */
  459.  
  460. #pragma argsused
  461.  
  462. void _FpeDefault( int SubType )
  463. {
  464. static char fpMsg[] = "Floating Point: Square Root of Negative Number";
  465. #define DIFF_LOC fpMsg + 16
  466.  
  467.         switch( SubType )
  468.             {
  469.             case FPE_INVALID:
  470.                 strcpy( DIFF_LOC, "Invalid" );
  471.                 break;
  472.             case FPE_DENORMAL:
  473.                 strcpy( DIFF_LOC, "DeNormal" );
  474.                 break;
  475.             case FPE_ZERODIVIDE:
  476.                 strcpy( DIFF_LOC, "Divide by Zero" );
  477.                 break;
  478.             case FPE_OVERFLOW:
  479.                 strcpy( DIFF_LOC, "Overflow" );
  480.                 break;
  481.             case FPE_UNDERFLOW:
  482.                 strcpy( DIFF_LOC, "Underflow" );
  483.                 break;
  484.             case FPE_INEXACT:
  485.                 strcpy( DIFF_LOC, "Inexact" );
  486.                 break;
  487.             case FPE_UNEMULATED:
  488.                 strcpy( DIFF_LOC, "Unemulated" );
  489.                 break;
  490.             case FPE_SQRTNEG:   // no copy here: message is already right
  491.                 break;
  492.             case FPE_STACKOVERFLOW:
  493.                 strcpy( DIFF_LOC, "Stack Overflow" );
  494.                 break;
  495.             case FPE_STACKUNDERFLOW:
  496.                 strcpy( DIFF_LOC, "Stack Underflow" );
  497.                 break;
  498.             case FPE_EXPLICITGEN:
  499.                 strcpy( DIFF_LOC, "Exception Raised" );
  500.                 break;
  501.             }
  502.         _errorExitBox( fpMsg, 3 );
  503. }
  504.  
  505. static void default_action( int SigType )
  506. {
  507.         switch (SigType)
  508.         {
  509.         case SIGABRT    :
  510.                 _errorExitBox( "Program Aborted", 3 );
  511.                 break;
  512.         case SIGINT     :
  513.                 geninterrupt( 0x23 );
  514.                 break;
  515.         case SIGILL     :
  516.                 _errorExitBox( "Illegal Instruction", 1 );
  517.                 break;
  518.         case SIGSEGV    :
  519.                 _errorExitBox( "Segment Violation", 1 );
  520.                 break;
  521.         case SIGFPE     :
  522.                 _errorExitBox( "Floating Point Trap", 1 );
  523.                 break;
  524.         case SIGTERM    :
  525.                 _errorExitBox( "Program Terminated", 1 );
  526.                 break;
  527.         default         :
  528.                 _errorExitBox( "Abnormal Program Termination", 1 );
  529.                 break;
  530.         }
  531. }
  532.  
  533. #endif  // !_Windows
  534.  
  535. int _FARFUNC raise(int SigType)
  536. {
  537.         int             Index;
  538.         _CatcherPTR     action;
  539. #ifdef _BUILDRTLDLL
  540.         unsigned        LocalDS;
  541. #endif
  542.  
  543.         if ((Index = GetIndex(SigType)) == BogusSignal)
  544.                 return 1;
  545.  
  546.         if ((action = Dispatch[Index]) != SIG_IGN)
  547.                 if (action == SIG_DFL)
  548. #ifdef _Windows
  549.                         if( SigType == SIGFPE )
  550.                             _FpeDefault( FPE_EXPLICITGEN );
  551.                         else
  552. #endif
  553.                             default_action( SigType );
  554.                 else
  555.                 {       /*
  556.                         Call user routine. Add optional parameter
  557.                         specifing that the signal was raised explicitly
  558.                         rather than asynchronously.
  559.                         */
  560. #ifdef ANSI_CONFORMING
  561.                         Dispatch[Index] = SIG_DFL; /* Always default (ANSI) */
  562. #else
  563.                         if (SigType != SIGFPE)     /* Maybe default (MS) */
  564.                                 Dispatch[Index] = SIG_DFL;
  565. #endif
  566.  
  567. #ifdef _BUILDRTLDLL
  568.                         LocalDS = _DS;
  569.                         _DS = SavedDS[Index];
  570. #endif
  571.                         (*action)(SigType, ExplicitVal[Index]);
  572. #ifdef _BUILDRTLDLL
  573.                         _DS = LocalDS;
  574. #endif
  575.                 }
  576.         return 0;
  577. }
  578.  
  579. #ifdef _Windows
  580.  
  581. void _FARFUNC _FpeHandler(int subcode)
  582. {
  583.         register _CatcherPTR    action;
  584. #ifdef _BUILDRTLDLL
  585.         unsigned                LocalDS;
  586. #endif
  587.  
  588.         if ((action = Dispatch[2]) != SIG_IGN)
  589.         {
  590.                 if ((action == SIG_DFL) || (action == SIG_ERR))
  591.                         _FpeDefault(subcode);
  592. #ifdef ANSI_CONFORMING
  593.                 Dispatch[2] = SIG_DFL;          /* Reset signal */
  594. #endif
  595. #ifdef _BUILDRTLDLL
  596.                 LocalDS = _DS;
  597.                 _DS = SavedDS[2];
  598. #endif
  599.                 (*action)(SIGFPE, subcode);    /* Call handler */
  600. #ifdef _BUILDRTLDLL
  601.                 _DS = LocalDS;
  602. #endif
  603.         }
  604. }
  605.  
  606. #endif // _Windows
  607.  
  608. #pragma warn .pro
  609.