#include #include #include #include /** Define a jump buffer to handle error conditions. ** Data type jmp_buf defined in setjmp.h. **/ static jmp_buf env; /* file scope */ #define Ok (0) void jumper( int ), divisionFP( void ); int guard( void ); main() { /** Trap signals generated by floating-point ** errors such as division by zero. **/ signal( SIGFPE, jumper ); /** Loop until error condition occurs. **/ while ( Ok == guard() ) ; } /** Jump out of this function to the jump destination, ** which is the point after the call to setjmp. In ** our case, the jump point occurs right after the ** if-test in function guard. **/ void jumper( int status ) { printf( "Signal status == %d.\n", status ); longjmp( env, 1 ); /** This code is executed only if longjmp fails. **/ fprintf( stderr, "*** longjump returned!! ***\n" ); exit( EXIT_SUCCESS ); } /** Scan the standard input for two floats and ** divide the first by the second. **/ void divisionFP( void ) { float f1, f2; printf( "Two floats: " ); scanf( "%f %f", &f1, &f2 ); printf( "%f / %f == %f\n", f1, f2, f1 / f2 ); } /** Set a jump point for return from an error ** condition, in this case an error resulting ** from a floating-point operation. The function ** signal is invoked in main to trap such errors. ** Return Ok (0) if the floating-point operation ** succeeds; otherwise, the nonlocal jump ** of longjmp intervenes. **/ int guard( void ) { int s; /** Set jump point, which is right after the if-test **/ if ( ( s = setjmp( env ) ) != Ok ) { /* jump point */ fprintf( stderr, "At jump point and about to exit...\n" ); exit( EXIT_SUCCESS ); } divisionFP(); return Ok; }