How can I catch a ctrl-c event?
Asked Answered
M

4

169

How do I catch a Ctrl+C event in C++?

Meistersinger answered 29/10, 2009 at 1:39 Comment(3)
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
F
209

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;    
}
Flop answered 29/10, 2009 at 1:55 Comment(9)
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
M
67

For a Windows console app, you want to use SetConsoleCtrlHandler to handle CTRL+C and CTRL+BREAK.

See here for an example.

Miquelmiquela answered 29/10, 2009 at 2:29 Comment(0)
S
50

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;

}
State answered 29/10, 2009 at 1:41 Comment(3)
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
S
2

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.

Stepup answered 29/10, 2009 at 1:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.