1

am having a little issue to make the program count the number of times a signal is sent to the child process. Wrong value is being displayed. The parent should send each element of the array through the pipe to the child, then the child should read and display what was sent. count holds the number of signals sent to child. Any help please?

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

int count = 0;//number of SIGUSR1 signal sent to child by parent

void sigHandler(int signum){
    signal(SIGUSR1, sigHandler);
    if (signum == SIGINT){
        printf("SINGINT Received\n");
        count++;
    }   
}

int main(void){
    int pid, fd[2], ato, i;
    pipe(fd);
    pid = fork();
    int x[] = {1, 2, 3, 4, 5, 6, 7};
    char bufP[3], bufC[3];
    signal(SIGINT, sigHandler);
    if (pid == 0){
        //child         
        printf("I am Child\n");     
        close(fd[1]);
        read(fd[0], bufC, sizeof(bufC));
        close(fd[0]);
        ato = atoi(bufC);
        printf("Child read: %d\n", ato);
        sleep(2);
    }else{
        //parent
        printf("I am Parent\n");            
        for (i=0; i<7; i++){
            close(fd[0]);
            sprintf(bufP, "%d", x[i]); 
            write(fd[1], bufP, sizeof(bufP));                
            close(fd[1]);               
            sleep(1);
            kill(pid, SIGINT);  //sending signal to child               
        }                       
    }       
    printf("Count: %d\n", count); //number of times signal was sent     
}

Thanks

Akzwitch
  • 113
  • 1
  • 2
  • 13
  • 2
    First [avoid using printf in a signal handler](http://stackoverflow.com/a/16891065/1673391), second because signal handler can be asynchronously so `count` type should be `sig_atomic_t` - also read [What happens during this signal handling program?](http://stackoverflow.com/q/21707588/1673391) – Grijesh Chauhan Mar 10 '15 at 06:39
  • Also read this [Use reentrant functions for safer signal handling](http://www.ibm.com/developerworks/linux/library/l-reent/index.html#N101CA), after reading this blog you will be able to write your program correctly. – Grijesh Chauhan Mar 10 '15 at 06:50
  • Why do you close `fd[0]` and `fd[1]` seven times? Not only that, but you try to write to `fd[1]` after you close it. Also, how many signals are you expecting to get? Your child has no loop so it will print after 2 seconds. You will only get around 2 signals in that time. – JS1 Mar 10 '15 at 07:13
  • Your program seems to be doing two different things: Interprocess communication via pipes and counting of signals. Try to narrow it down to just one thing to simplify the code, as it will make it easier for you to spot problems. Here's some random observations: 1. You're counting SIGINT, not SIGUSR1. Why is your signal handler installing another signal handler? 2. You're installing the SIGINT handler for both the parent and the child. Was that intended? 3. Like JS1 said, you can't `close()` and then `read()` in the next iteration -- it'll be closed. – Ulfalizer Mar 10 '15 at 14:56

1 Answers1

1

It is not safe to count signals. Multiple kill signals can be merged into a on signal reception on the receiver. Think of the kill/signal as hardware interrupt signals. Use them for nudging only, but do not rely on each one will be received unmerged with other instances of the same signal value.

Stian Skjelstad
  • 2,277
  • 1
  • 9
  • 19