sigint called multiple times instead of one (C)

sigaction
sigaction(sigint)
kill c example
man sigchld
c shell signal handler
signal handler only works once
send signal to process c
sigint handler

This is a snippet of my code:

signal (SIGINT, ( void *)sig_handler); 

while(1){
    newsockd = -1;
    memset(&cli_addr, 0, sizeof(cli_addr));

    if((newsockd = accept(sockd, (struct sockaddr *) &cli_addr, (socklen_t *) &socket_len)) < 0){
        perror("Errore nella connessione\n");
        onexit(newsockd, sockd, 0, 2);
    }
    fprintf(stdout, "Ricevuta richiesta di connessione dall' indirizzo %s\n", inet_ntoa(cli_addr.sin_addr));

    child_pid = fork();
    if(child_pid < 0){
        perror("Fork error");
        onexit(newsockd, sockd, 0, 2);
    }
    if(child_pid == 0){
        do_child(newsockd);
        exit(0);
    }
    else{
       while(waitpid(child_pid, NULL, WNOHANG) > 0)
        continue;
       }
    }
}

and the function sig_handler:

void sig_handler(const int signo, const int sockd, const int newsockd){
  if (signo == SIGINT){
    printf("Received SIGINT, exiting..\n");
    if(newsockd) close(newsockd);
    if(sockd) close(sockd);
    exit(EXIT_SUCCESS);
  }
}

The problem happens when i press "CTRL+C" because sighandler is called multiple times. Example:

  1. Server is listening;
  2. 2 x Connection received;
  3. 2 x child fork;
  4. 2 x child are closed;
  5. now i want to close the server so i press CTRL+C;

expected output: received SIGINT, exiting.... real output: received SIGINT, exiting.... received SIGINT, exiting.... received SIGINT, exiting.... Why i got this behaviour?

EDIT: code updated This is what happens when 1 fork is done and when the child has finished i close the server:

^C7518
7516
Received SIGINT, exiting...
Received SIGINT, exiting...

SOLUTION FOUND: the problem was that i haven't write exit(0) after the instruction do_child()...code updated!


The signal is sent to every child process of the current process. In your code, when you're using fork, you create a child process that inherits from the main process the SIGINT handler. That's why the message is printed several times.

SIGINT handler runs only once, sig-deadlock.c */ #include <stdio.h> #include <stdlib.h> #include <signal.h> #​include calls sigaction(2) using flags that supply BSD semantics. One more prerequisite that wasn't emphasized here. w/ catch once behaviour and sometimes w/ catch every time behaviour tipped me off to some kind of  printf(“received SIGINT %s times ”, counter); Since counter is of type ‘int’ so you need to use %d instead of %s in the line above. Let me know if this solves your problem…


There are few observations,

1)You should better use sigaction instead of signal function. http://pubs.opengroup.org/onlinepubs/7908799/xsh/sigaction.html

2)Now some fixes in your current code. You may use

if(child_pid == 0)
{
   /*Now in the child make again the action for SIGINT default, so that 
   your handler does not get called.*/ 
       signal (SIGINT, SIG_DFL);
       do_child(newsockd);
}   

3)Why you are calling waitpid in the main loop? You should have a handler for SIGCHLD and then use wait/waitpid inside it.

Ideally after creating a child to serve client, the main loop should go back to accept. (If it is geeting blocked after creation of a child then how your server becomes a concurrent server?)

(Or for the first version, I would suggest you avoid this instead use, after your call to signal handler for SIGINT,

signal(SIGCHLD, SIG_IGN);  //This should  automatically get rid of zombies.

(Pl. experiment this in your system)

Link for reference - http://en.wikipedia.org/wiki/SIGCHLD

4)It seems your argument to the handler for SIGINT is also not proper.The proper prototype is

void (*signal(int sig, void (*func)(int)))(int);

But your handler is

void sig_handler(const int signo, const int sockd, const int newsockd).

How the values of sockfd & newsockfd are getting passed? Link

http://pubs.opengroup.org/onlinepubs/009696899/functions/signal.html

Handling Multiple Signal Types, signal(SIGINT, INThandler); signal(SIGQUIT, QUIThandler); void In the above example, SIGhandler() is installed to handle more than one signals. When it is called, the argument sig contains the signal name that should be processed. int i, j; void INThandler(int sig) { char c; signal(SIGINT, SIG_IGN); signal(SIGALRM,  why multiple SIGINT raises when i hit C-c hi, in my application, i have set up to capture SIGINT and execute a handler.the problem is whenever i hit C-c, multiple SIGINT are sent to the application.I have blocked the SIGINT right after catching the first one but it is unsuccessful.Here is what i do : jmp_buf main_loop; int


I am not sure how you kill the child process.If the child process is not in Zomb status yet, your sign_handler will work on it. May need add more log to clarify the sequence of child process life cycles.

Military Intelligence, Many of the traditional SIGSEC functions are applicable in the C-SIGINT arena. of instruction (POI) pertaining to CSIGINT training at skill levels one and three. To develop this capability, a prototype system called the Army CLASSIC FOX Specific time frames for delivery of the prototypes are not yet firm; however, the  why multiple SIGINT raises when i hit C-c hi, in my application, i have set up to capture SIGINT and execute a handler.the problem is whenever i hit C-c, multiple SIGINT are sent to the application.I have blocked the SIGINT right after catching the first one but it is unsuccessful.Here is what i do : jmp_buf main_loop; int


On a related note: I found that I was getting multiple SIGINT for a single CTRL+C as well. When I checked my task manager, I actually had multiple hung node.js scripts for this application. Once I terminated them in task manager, I started receiving single SIGINT as expected.

TCP/IP Sockets in C: Practical Guide for Programmers, If the same signal is delivered more than once while it is being handled, the handler is signal handler for SIGINT sleeps for three seconds and returns, instead of exiting. the program, hit the interrupt key (Control-C) several times in succession. signals need to be prepared for these erroneous returns from those calls  This is really weird: If, and only if, I press ctrl+C multiple times, quickly (more than once a second), yum keeps trying mirrors until there is no more mirrors to try. If I press ctrl+C a few times and then stop, yum shows "Trying other mirror" after the error, freeze for a few seconds, and eventually it exits (sometimes after trying one or


[PDF] Signals, Even though most systems can only execute one process at a time. ▫ Except possibly with lower Called once, returns twice Corresponding Event. 2 SIGINT. Terminate. Interrupt (e.g., ctl-c from keyboard) this time returning i instead of 0. It could also intercept a SIGINT signal which is sent when you stop running a program via the ctrl+c command. In python, this can be done using the signal module which can intercept the above signals.


signal, In general you can cause a program to simply exit by pressing ^C, and you can A SIGHUP, SIGINT, or SIGTERM signal causes the program to exit. set of asynchronous signals and instead delivers them over one or more registered channels. If the program has not called Notify to receive SIGPIPE signals, then the  Does Ctrl-C (SIGINT) prevent output to be shown even if there were processes trying to output it I had a bash script which did the wrong thing. So I pressed Ctrl-C to stop it.


Running script with @babel/node triggers SIGINT event twice · Issue , Input Code Run this code with babel-node process.on('SIGINT', Should be called once. We really appreciate you taking the time to report an issue. child process) since child process will be the first one to receive CTRL + C (being then this should have been done for SIGTERM and not SIGINT since  I note FreeBSD sh doesn't abort either when the cmd exits with exit(130) either, which is a common way to report the death by SIGINT of a child (mksh does a exit(130) for instance if you interrupt mksh -c 'sleep 10;:').