home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / c / other / learn / signal1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-26  |  3.2 KB  |  119 lines

  1. /* SIGNAL.C illustrates setting up signal interrupt routines. Functions
  2.  * illustrated include:
  3.  *      signal          abort           raise           _fpreset
  4.  *
  5.  * The program also illustrates saving an environment and then doing a
  6.  * long jump to return to it using functions:
  7.  *      setjmp          longjmp
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <conio.h>
  12. #include <signal.h>
  13. #include <process.h>
  14. #include <setjmp.h>
  15. #include <stdlib.h>
  16. #include <float.h>
  17.  
  18. void ctrlchandler( void );          /* Prototypes */
  19. void aborthandler( void );
  20. void fphandler( int sig, int num );
  21.  
  22. jmp_buf mark;                       /* Address for long jump to jump to */
  23.  
  24. main()
  25. {
  26.     double n1, n2, r;
  27.     int jmpret;
  28.  
  29.     /* Modify abort behavior. */
  30.     if( signal( SIGABRT, aborthandler ) == SIG_ERR )
  31.     {
  32.         printf( "Couldn't set SIGABRT\n" );
  33.         exit( 1 );
  34.     }
  35.  
  36.     /* Modify CTRL+C behavior. */
  37.     if( signal( SIGINT, ctrlchandler ) == SIG_ERR )
  38.     {
  39.         fprintf( stderr, "Couldn't set SIGINT\n" );
  40.         abort();
  41.     }
  42.  
  43.     /* Set up pointer to error handler. */
  44.     if( signal( SIGFPE, fphandler ) == SIG_ERR )
  45.     {
  46.         fprintf( stderr, "Couldn't set SIGFPE\n" );
  47.         abort();
  48.     }
  49.  
  50.     /* Save stack environment for return in case of error. First time
  51.      * through, jmpret is 0, so true conditional is executed. If an
  52.      * error occurs, jmpret will be set to -1 and false conditional
  53.      * will be executed.
  54.      */
  55.     jmpret = setjmp( mark );
  56.     if( jmpret == 0 )
  57.     {
  58.         /* Try forcing error by dividing by 0 or using very large numbers. */
  59.         printf( "Enter number to divide or CTRL-C: " );
  60.         scanf( "%lf", &n1 );
  61.         printf( "Enter number to divide by or CTRL-C: " );
  62.         scanf( "%lf", &n2 );
  63.         r = n1 / n2;
  64.  
  65.         /* This won't be reached if error occurs. */
  66.         printf( "\n%4.3g / %4.3g = %4.3g\n", n1, n2, r );
  67.     }
  68.     else
  69.         printf( "Recovered from floating-point error\n" );
  70.  
  71.     /* Fake CTRL+C. Program will abort or exit, depending on user
  72.      * response in handler.
  73.      */
  74.     raise( SIGINT );
  75.     exit( 0 );
  76. }
  77.  
  78. /* Function called whenever SIGINT (CTRL+C) interrupt is called. */
  79. void ctrlchandler()
  80. {
  81.     int ch;
  82.  
  83.     /* Disallow CTRL+C during handler. */
  84.     signal( SIGINT, SIG_IGN );
  85.  
  86.     printf( "Abort processing? " );
  87.     ch = getche();
  88.     printf( "\n" );
  89.     if( (ch == 'y') || (ch == 'Y') )
  90.         abort();
  91.     else
  92.  
  93.         /* The CTRL+C interrupt must be reset to our handler since by
  94.          * default DOS resets it to the system handler.
  95.          */
  96.         signal( SIGINT, ctrlchandler );
  97. }
  98.  
  99. /* Function called whenever SIGABRT interrupt is called. */
  100. void aborthandler()
  101. {
  102.     printf( "The abort() function was called\n" );
  103.     exit( 1 );
  104. }
  105.  
  106. /* Function called whenever SIGFPE interrupt is called. */
  107. void fphandler( int sig, int num )
  108. {
  109.     printf( "Signal: %d   Subcode: 0x%x\n", sig, num );
  110.  
  111.     /* Initialize floating-point package. */
  112.     _fpreset();
  113.  
  114.     /* Restore calling environment and jump back to setjmp. Return -1
  115.      * so that setjmp will return false for conditional test.
  116.      */
  117.     longjmp( mark, -1 );
  118. }
  119.