Handle CTRL+C on Win32
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;
}
What exactly is the effect of Ctrl-C on C++ Win32 console applications?
EDIT: SIGINT, not SIGTERM. And Assaf reports that no objects are destroyed (at least on Windows) for unhanded SIGINT.
The system sends a SIGINT. This concept applies (with some variance) for all C implementations. To handle it, you call signal, specifying a signal handler. See the documentation on the signal function at Open Group and MSDN.
The second question is a little trickier, and may depend on implementation. The best bet is to handle the signal, which allows you to use delete
and exit()
manually.
My consoleHandler does not handle CTRL+C even though properly set
From MSDN:
CTRL+BREAK is always treated as a signal, but typical CTRL+C behavior
can be changed in three ways that prevent the handler functions from
being called:
- The SetConsoleMode function can disable the ENABLE_PROCESSED_INPUT mode for a console's input buffer, so CTRL+C is reported as keyboard
input rather than as a signal.- Calling SetConsoleCtrlHandler with the NULL and TRUE arguments causes the calling process to ignore CTRL+C signals. This attribute is
inherited by child processes, but it can be enabled or disabled by any
process without affecting existing processes.- If a console process is being debugged and CTRL+C signals have not been disabled, the system generates a DBG_CONTROL_C exception. This
exception is raised only for the benefit of the debugger, and an
application should never use an exception handler to deal with it. If
the debugger handles the exception, an application will not notice the
CTRL+C, with one exception: alertable waits will terminate. If the
debugger passes the exception on unhandled, CTRL+C is passed to the
console process and treated as a signal, as previously discussed.
Perhaps the third point applies to your problem? Does your application behaves as expected when running in Release mode?
How can I catch a ctrl-c event?
signal
isn't the most reliable way as it differs in implementations. I would recommend using sigaction
. Tom's code would now look like this :
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
void my_handler(int s){
printf("Caught signal %d\n",s);
exit(1);
}
int main(int argc,char** argv)
{
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = my_handler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
pause();
return 0;
}
Windows handling CTRL+C in different thread?
From MSDN topic HandlerRoutine:
A HandlerRoutine function is an application-defined function used with the SetConsoleCtrlHandler
function. A console process uses this function to handle control signals received by the process. When the signal is received, the system creates a new thread in the process to execute the function.
So, the answer is: this is impossible.
Related Topics
Why Does Not a Template Template Parameter Allow 'Typename' After the Parameter List
Why Is Cmake Designed So That It Removes Runtime Path When Installing
Automatically Generate C++ File from Header
Is It a Good Practice to Use Unions in C++
Double to String Without Scientific Notation or Trailing Zeros, Efficiently
Clean Up Your #Include Statements
C++ Linux Double Destruction of Static Variable. Linking Symbols Overlap
Decltype, Result_Of, or Typeof
Why Does Initializing an Extern Variable Inside a Function Give an Error
C++, Function Pointer to the Template Function Pointer
C++ Bitfield Packing with Bools
Comparing Two Integers Without Any Comparison
Std::Unordered_Map::Find Using a Type Different Than the Key Type
Typeid() Returns Extra Characters in G++
Difference Between File Scope and Global Scope