Installs a signal handler #include <signal.h> void ( * signal ( int sig , void (*handler )(int) ) )(int); The signal( ) function specifies a function to be executed when the program receives a given signal. The parameter handler is a pointer to a function that takes one argument of type int and has no return value. This pointer may be the address of a function defined in your program, or one of two macros defined in the header file signal.h. The handler argument works in the following ways (assuming that the call to signal( ) is successful):
The return value of signal( ) is also a function pointer: it has the same type as the handler parameter. If the signal( ) function succeeds in installing the new handler, it returns a pointer to the previous handler (which may be SIG_IGN or SIG_DEF, if the program has not installed any other handler for the given signal). If unsuccessful, signal( ) returns the value of SIG_ERR and sets the errno variable to an appropriate value. Signals are sent through the operating system by other programs, or are raised by system interrupts, or by the program itself using the raise( ) function. According to the C standard, the following signals are defined in all implementations. The macros listed here represent the permissible values of the signal( ) function's integer argument sig, as well as the argument value passed to the signal handler installed when the signal occurs.
Specific systems may also define other signal types, as well as macros for other special values of handler. Furthermore, many systems do not allow programs to install signal handlers for, or to ignore, certain signals. For example, Unix systems do not allow programs to handle or ignore a SIGKILL or SIGSTOP signal. The first three signals in the previous listSIGFPE, SIGILL, and SIGSEGVare non-recoverable. In other words, if you use signal( ) to install a handler for one of these signals, your handler function should never return. If it does, the program's behavior is undefined. For other signal types, when a signal handler returns, the program resumes execution wherever it was when the signal occurred. Signal handler functions are also subject to other constraints, as the state of the system and the program is undefined at the time of their execution. They must not access objects with static storage class, except objects declared with the type sig_atomic_t and the qualifier volatile. Signal handlers must also avoid calling any other functions except abort( ), _Exit( ), or signal( ), and may call signal( ) only to set a handler for the signal type that caused the present function call. Otherwise the program's behavior is undefined. These restrictions do not apply to handlers invoked through calls to abort( ) or raise( ), however. Handlers invoked through abort( ) or raise( ) must not call raise( ). Certain systems specify other functions besides abort( ), _Exit( ), and signal( ) that a signal handler may call safely. In particular, the POSIX standards define such "safe functions," as well as functions for finer control of signal handling. Example# include <stdio.h> # include <stdlib.h> # include <stdint.h> // Defines SIG_ATOMIC_MAX # include <signal.h> void sigint_handler(int sig); volatile sig_atomic_t i; // A counter accessed by main and the handler. int main( ) { if ( signal( SIGINT, sigint_handler ) == SIG_ERR ) { perror("Failed to install SIGINT handler"); exit(3); } while (1) { puts( "Press Ctrl+C to interrupt me."); for ( i = 0 ; i < SIG_ATOMIC_MAX ; i++ ) if ( i % 100000 == 0) { printf( "\r%d ", i / 100000 ); fflush( stdout ); } raise( SIGINT ); // Simulate a Ctrl+C in case the user didn't type it. } return 0; } void sigint_handler( int sig ) { char c; if ( sig != SIGINT ) exit( 1 ); signal( SIGINT, SIG_IGN ); // Ignore a second Ctrl+C puts( "\nThis is the function sigint_handler( )." "\nDo you want to exit the program now? [y/n]"); while (( c = tolower( getchar( ) )) != 'y' && c != 'n' ) ; if ( c == 'y' ) exit(0); else i = 0; // Reset timer signal( SIGINT, sigint_handler ); // Reinstall this handler. /* No return value; just fall off the end of the function. */ } See Also |