How do I catch a Ctrl+C event in C++?
How can I catch a ctrl-c event?
Console application, windows application, or what? –
Boccie
Which OS Windows, Linux, etc.. –
Crambo
Well, it's a Qt app, but I'm running it from the console during development. (This is Linux) –
Meistersinger
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;
}
I think my_handler should take
int s
as it's argument. sig_t
is itself a function pointer type. –
Tribromoethanol <stdlib.h>, etc - it's C, not C++. In C++ you should use <cstdlib> –
Vyky
Works on OSX. In my main.mm file, I didn't even need to include signal.h, stdlib.h, or unistd.h. I just included stdio.h and Foundation/Foundation.h, and then if I needed to do std::cout stuff for outputting a shutdown message, I included iostream. –
Kowalczyk
printf()
isn't async-signal-safe, so can't be used inside signal handler. –
Dineric These functions are not available on Windows. –
Glossary
would be nice to have some explanation about
sa_mask
and sa_flags
. –
Blakely @Glossary No doubt you've figured it out by now, but for anyone else wondering: these are posix calls, which work on Linux and Unix systems. For windows you have to use the windows api. –
Alluvium
@FelisPhasma: Being Posix doesn't really have much to do with it. Windows includes support for a decent number of Posix functions. –
Glossary
Is there a reason to
exit(1)
instead of exit(s)
in my_handler
? For me this loses information if for instance you want to manage (or just log) exit value ($?
). –
Lattie For a Windows console app, you want to use SetConsoleCtrlHandler to handle CTRL+C and CTRL+BREAK.
See here for an example.
You have to catch the SIGINT signal (we are talking POSIX right?)
See @Gab Royer´s answer for sigaction.
Example:
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
void my_handler(sig_t s){
printf("Caught signal %d\n",s);
exit(1);
}
int main(int argc,char** argv)
{
signal (SIGINT,my_handler);
while(1);
return 0;
}
Yes, it's POSIX. I forgot to add Linux to the question. –
Meistersinger
signal() behaves differently, depending if it follows BSD or SysV style. sigaction() is preferable. –
Timer
I know it is old, but this does not compile in g++ (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0. I had to change
void my_handler(sig_t s)
to void my_handler(sig_atomic_t s)
. –
Seineetmarne Yeah, this is a platform dependent question.
If you are writing a console program on POSIX,
use the signal API (#include <signal.h>
).
In a WIN32 GUI application you should handle the WM_KEYDOWN
message.
© 2022 - 2024 — McMap. All rights reserved.