The following code catches the “SIGINT” signal only once and then interrupts (program exists):
#include <signal.h>
#include <stdio.h>
void IntHandler(int value);
void CatchIntSignal()
{
struct sigaction intAction;
intAction.sa_handler = IntHandler;
sigemptyset(&intAction.sa_mask);
intAction.sa_flags = 0;
//if to uncomment any of "0" or "SIG_IGN" - IntHandler will be never called:
//intAction.sa_sigaction = 0/*SIG_IGN*/;
if(sigaction(SIGINT, &intAction, NULL) != 0)
{
printf("sigaction() failed.\n");
}
}
void IntHandler(int value)
{
printf("IntHandler(%d)\n", value);
//uncommenting this does not help:
//CatchIntSignal();
}
int main()
{
CatchIntSignal();
getchar();
return 0;
}
How must I modify this code to preserve program’s exit after SIGINT catching?
If to set intAction.sa_sigaction to 0 or to SIG_IGN – IntHandler will never be called – but why? Which undefined value does it have to say system that “it’s necessary to call IntHandler”? If I will set some handler to intAction.sa_sigaction – this handler will be called (but IntHandler will not). How does system know that I did set something to intAction.sa_sigaction?
Your problem is that the
sa_handlerandsa_sigactionfields ofstruct sigactionare actually the same field. Quoting the (OSX) manpage forsigaction(2):So your assignment to
sa_sigactionis overwriting the handler you already set. You should just setsa_handlerand leavesa_sigactionalone. This is howCatchIntSignalshould read:(You may need to add #includes of
string.handerrno.hto get thestrerror(errno)bit to compile. Always includestrerror(errno)in error messages triggered when system calls fail.)(CORRECTION: added
SA_RESTARTto flags per ninjalj.)