Here is a simple application that handled CTRL+C signal both on linux and windows:
#include <QtCore/QCoreApplication>
#include <QDebug>
#include <QThread>
void SigIntHandler()
{
qDebug()<<"SigInt ThreadID: "<<QThread::currentThreadId();
qApp->quit();
}
#ifdef __linux__
#include <signal.h>
void unix_handler(int s)
{
//svakako je SIGINT, ali da ne javlja warning da se s ne koristi
if (s==SIGINT)
SigIntHandler();
}
#else
#include <windows.h>
BOOL WINAPI WinHandler(DWORD CEvent)
{
switch(CEvent)
{
case CTRL_C_EVENT:
SigIntHandler();
break;
}
return TRUE;
}
#endif
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//kod za hvatanje CTRL+C - unix i windows
#ifdef __linux__
signal(SIGINT, &unix_handler);
#else
SetConsoleCtrlHandler((PHANDLER_ROUTINE)WinHandler, TRUE);
#endif
qDebug()<<"Main ThreadID: "<<QThread::currentThreadId();
return a.exec();
}
After compiling and running it on linux (Debian Squeeze), I get following output:
/Test-build-desktop$ ./Test
Main ThreadID: 140105475446560
^CSigInt ThreadID: 140105475446560
/Test-build-desktop$ ./Test
Main ThreadID: 140369579480864
^CSigInt ThreadID: 140369579480864
/Test-build-desktop$ ./Test
Main ThreadID: 140571925509920
^CSigInt ThreadID: 140571925509920
And that's what I've expected (SigIntHandler method runs on main thread). But when I compile and execute same code on Windows 7, I get this:
d:\Test-build-desktop\debug>Test.exe
Main ThreadID: 0x5a8
SigInt ThreadID: 0x768
d:\Test-build-desktop\debug>Test.exe
Main ThreadID: 0x588
SigInt ThreadID: 0x1434
d:\Test-build-desktop\debug>Test.exe
Main ThreadID: 0x1170
SigInt ThreadID: 0xc38
As you can see, here SigIntHandler method is executed in different thread then main ... And that creates me many problems. So my question is - is it possible to force SigIntHandler to run in main thread on windows ? Am I maybe catching siging wrong ?
Thanks !!
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.
SIGINT can be send to program using windows-kill, by syntax windows-kill -SIGINT PID , where PID can be obtained by Microsoft's pslist. Regarding catching SIGINTs, if your program is in Python then you can implement SIGINT processing/catching like in this solution.
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.
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.
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