0

I have built a function (based in a example) that allows me to ignore the signal SIGINT. That function counts the times that the user press CONTROL + C (the interruption SIGINT). The function is the following one

#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

sig_atomic_t sigint_count = 0;

void handler (int signal_number)
{
    ++sigint_count;
    printf ("SIGINT was raised %d times\n", sigint_count);
}

int main ()
{
    struct sigaction sa; //Declaração da estrutura sigaction
    memset (&sa, 0, sizeof (sa));//Libertação da memória usada
    sa.sa_handler = &handler;
    sigaction (SIGINT, &sa, NULL);
    while(1);
    return 0;
}

My doubt is about this line of code

 sigaction (SIGINT, &sa, NULL);

I tried to write another thing different to NULL but it doesn't work. Why NULL? What is the meaning of that NULL in sigaction?

PS: it works as I want tho

sg7
  • 6,108
  • 2
  • 32
  • 40
João
  • 13
  • 1
  • 8
  • 1
    [man 2 sigaction](http://man7.org/linux/man-pages/man2/sigaction.2.html) – cadaniluk Mar 31 '18 at 22:27
  • I already read this same web page but I still don't understand... – João Mar 31 '18 at 22:29
  • 1
    What specifically don't you understand? The man page says verbatim "If oldact is non-NULL, the previous action is saved in oldact." To me, there is nothing there *not* to understand, but if you do anyway, tell us what precisely it is. – cadaniluk Mar 31 '18 at 22:34
  • Please, exactly what "*doesn't work*"? – alk Apr 01 '18 at 07:18
  • OT: Among many other functions it is not save to call `printf()` from a signal handler. – alk Apr 01 '18 at 07:21

1 Answers1

0

The declaration of sigaction is:

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

The old action, that is the one you are replacing, is written to the pointer in the third argument. If you don't need this result, you can provide NULL to ignore it.

If oldact is non-NULL, the previous action is saved in oldact.

Getting the old action is usefull to temporarily replace it.

For example, modify your code like this:

volatile sig_atomic_t sigint_count = 0;
...
    struct sigaction backup;
    sigaction (SIGINT, &sa, &backup);
    while(sigint_count < 10) {}
    sigaction (SIGINT, &backup, NULL);
    printf("^C again will terminate me.\n");
    while(1){}

declare the sig_atomic_t variable as volatile if it is accessed from concurrent contexts. If you don't, the compiler might "cache" the value in a register and the while(<) is endless

thejonny
  • 488
  • 2
  • 9