Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle CTRL+C on Win32

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?

like image 700
eang Avatar asked Aug 17 '13 17:08

eang


People also ask

What does Ctrl-C do in command prompt?

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.

How do you Ctrl break in CMD?

(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.

What is Sigbreak?

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.


1 Answers

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;
}
like image 98
lpapp Avatar answered Sep 23 '22 17:09

lpapp