2

Consider the following code:

#include <signal.h>
#include <stdio.h>

    void catch ()
    {
        printf("hi\n");
    }
    int main()
    {
        struct sigaction act;
        act.sa_handler = catch;
        sigaction(SIGINT, &act, NULL);
        for(;;);
        return 0;
    }

When this program is run. The first time I press CTRL-C it prints "hi".
But the second time the program exits. what could be the reason for this?
What I wanted was that the program catch the signal each time it is raised.

Rachid K.
  • 4,490
  • 3
  • 11
  • 30
asha rani
  • 41
  • 6
  • On a side note, you shouldn't call `printf` from a signal handler as it is not guaranteed to be a signal safe function. See [the signal-safety(7) man page](https://man7.org/linux/man-pages/man7/signal-safety.7.html). – Daniel Walker Dec 13 '20 at 18:54
  • 2
    You aren’t initializing the structure properly. You need to set the flags and the mask as well. – Jonathan Leffler Dec 13 '20 at 19:02

1 Answers1

3

If you don't use any SA_FLAG to explicitly define the behavior of "what to do after first catch of signal", it should be work.

Clear the contents of the sigaction, then initialize it.

memset(&act,0,sizeof(act)); // clear contents first
act.sa_handler = catch;
sigaction(SIGINT, &act, NULL);

See, sigaction(2).

In addition, do not use printf inside your signal handlers as Daniel pointed out. See signal-safety(7)

If you want to print something, or simply do something in your signal handler, you must use signal-safe functions. In your case, instead of using printf, you can use write() system call. See write(2).

By,

write(1,"hi\n",3); // 1 means standard out.
tango-1
  • 330
  • 1
  • 10
  • So if printf is unsafe is there any alternative way to print some text from inside signal handler? putting this code memset worked. So is it like once the signal is generated we need to clear the sigaction for it work again. Where is this clearing thing documented? Is it there in the man pages – asha rani Dec 13 '20 at 19:12
  • Calling `write` from a signal handler can overwrite `errno`, breaking error handling code –  Dec 13 '20 at 19:25
  • @StaceyGirl Good point. Signal handlers must do basic things, instead of doing complex I/O operations. – tango-1 Dec 13 '20 at 19:35
  • Is the `sigaction(SIGINT, &act, NULL);` this initialization complete ? As jonathan mentioned this is not correct way to initialize – asha rani Dec 14 '20 at 07:41
  • @asharani If you don’t want anything special, such as new signal mask, you can use this initializaton steps. By this way, your handler will have default behaviors. – tango-1 Dec 14 '20 at 07:55
  • @asharani As long as you use memeset(&act,0,sizeof(act)); as the answer mentions, it is ok. – nos Dec 14 '20 at 11:47
  • Is the SIGINT signal is same as what is called interrupt ? – asha rani Dec 14 '20 at 11:47