I have some problems with the handling of CTRL+C events, in a Win32 C++ console program.
Basically my program looks like this: (based on this other question: Windows Ctrl-C - Cleaning up local stack objects in command line app)
bool running;
int main() {
running = true;
SetConsoleCtrlHandler((PHANDLER_ROUTINE) consoleHandler, TRUE);
while (running) {
// do work
...
}
// do cleanup
...
return 0;
}
bool consoleHandler(int signal) {
if (signal == CTRL_C_EVENT) {
running = false;
}
return true;
}
The problem is the cleanup code not being executed at all.
After the execution of the handler function the process is terminated, but without execute the code after the main loop. What's wrong?
EDIT: as requested, this is a minimal test case similar to my program: http://pastebin.com/6rLK6BU2
I don't get the "test cleanup-instruction" string in my output.
I don't know if this is important, I'm compiling with MinGW.
EDIT 2: The problem with the test case program is the use of the Sleep()
function. Without it the program works as expected.
In Win32 the function handler runs in another thread, so when the handler/thread ends its execution the main thread is sleeping. Probably this is the cause of process interruption?
While in a command line such as MS-DOS, Linux, and Unix, Ctrl + C is used to send a SIGINT signal, which cancels or terminates the currently-running program. For example, if a script or program is frozen or stuck in an infinite loop, pressing Ctrl + C cancels that command and returns you to the command line.
(ConTRoL-Break) In a Windows PC, holding down the Ctrl key and pressing the Break key cancels the running program or batch file. See Ctrl-C.
By default, when a console window has the keyboard focus, CTRL + C or CTRL + BREAK is treated as a signal (SIGINT or SIGBREAK) and not as keyboard input. By default, these signals are passed to all console processes that are attached to the console. (Detached processes are not affected.
The following code works for me:
#include <windows.h>
#include <stdio.h>
BOOL WINAPI consoleHandler(DWORD signal) {
if (signal == CTRL_C_EVENT)
printf("Ctrl-C handled\n"); // do cleanup
return TRUE;
}
int main()
{
running = TRUE;
if (!SetConsoleCtrlHandler(consoleHandler, TRUE)) {
printf("\nERROR: Could not set control handler");
return 1;
}
while (1) { /* do work */ }
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With