Example: A Console Control Handler
Program 4-5 loops forever, calling the self-explanatory Beep function every 5 seconds. The user can terminate the program with a Ctrl-c or by closing the console. The handler routine will put out a message, wait 10 seconds, and, it would appear, return trUE, terminating the program. The main program, however, actually detects the Exit flag and stops the process. This illustrates the concurrent operation of the handler routine; note that the timing of the signal determines the extent of the signal handler's output. Examples in later chapters also use console control handlers.Note the use of WINAPI; this macro is used for user functions passed as arguments to Windows functions to assure the proper calling conventions. It is defined in the Microsoft C header file WTYPES.H.
Program 4-5. Ctrlc: Signal Handling Program
/* Chapter 4. Ctrlc.c */
/* Catch console events. */
#include "EvryThng.h"
static BOOL WINAPI Handler (DWORD CtrlEvent); /* See WTYPES.H. */
volatile static BOOL Exit = FALSE;
int _tmain (int argc, LPTSTR argv [])
/* Beep periodically until signaled to stop. */
{
/* Add an event handler. */
if (!SetConsoleCtrlHandler (Handler, TRUE))
ReportError (_T ("Error setting event handler."), 1, TRUE);
while (!Exit) {
Sleep (5000); /* Beep every 5 seconds. */
Beep (1000 /* Frequency. */, 250 /* Duration. */);
}
_tprintf (_T ("Stopping the program as requested.\n"));
return 0;
}
BOOL WINAPI Handler (DWORD CtrlEvent)
{
Exit = TRUE;
switch (CntrlEvent) {
/* Timing determines if you see the second handler message. */
case CTRL_C_EVENT:
_tprintf (_T ("Ctrl-c received. Leaving in 10 sec.\n"));
Sleep (4000); /* Decrease this to get a different effect. */
_tprintf (_T ("Leaving handler in 6 seconds.\n"));
Sleep (6000); /* Also try decreasing this time. */
return TRUE; /* TRUE indicates signal was handled. */
case CTRL_CLOSE_EVENT:
_tprintf (_T ("Leaving the handler in 10 seconds.\n"));
Sleep (4000);
_tprintf (_T ("Leaving handler in 6 seconds.\n"));
Sleep (6000); /* Also try decreasing this time. */
return TRUE; /* Try returning FALSE. Any difference? */
default:
_tprintf (_T ("Event: %d. Leaving in 10 seconds.\n"),
CntrlEvent);
Sleep (4000);
_tprintf (_T ("Leaving handler in 6 seconds.\n"));
Sleep (6000);
return TRUE;
}
}
