i wrote the below code: after fork() function the parent send a signal to child. i think the child receive the signal and terminates. i don't want the solution because i can solve it by two below ways. i want to know what is the cause of this problem?

what i tried at first is below code:

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

#define maxchild 1

int inchild=-1;

void sighandler(int signo){
    char buffer[256];
    int a,b=0;
    switch(signo){
    case SIGUSR1:
        printf("SIGUSR1\n");
        break;
    case SIGUSR2:
        printf("SIGUSR2\n");
        break;
}
}


int main(){
pid_t ids[maxchild];
struct sigaction control;
control.sa_flags=0;
control.sa_handler=sighandler;
sigemptyset(&control.sa_mask);
sigaction(SIGUSR1,&control,NULL);
sigaction(SIGUSR2,&control,NULL);
for(int i=0;i<maxchild;i++){
    ids[i]=fork();
    printf("here %d\n",ids[i]);
    if(ids[i]==0){
        printf("in child\n");
        inchild=i+1;
        break;
    }
}
while(inchild>=0) {
}
//  sleep(1);
if(inchild==-1){
    for(int i=0;i<maxchild;i++){
        printf("child: %d\n parent: %d\n",ids[i],getpid());
        kill(ids[i],SIGUSR1);
    }

}
  if (inchild==-1) wait(NULL);
    return 0;
}

when i run the code so many times, i expect to see the "SIGUSR1" in output every time but mostly the output is:

here 17573 (or any other positive number)
child: 17573
parent: 17572

and then program terminates suddenly. i understand i can solve it by two solution: 1. parent most sleep after fork() function:

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

#define maxchild 1

int inchild=-1;

void sighandler(int signo){
    char buffer[256];
    int a,b=0;
    switch(signo){
    case SIGUSR1:
        printf("SIGUSR1\n");
        break;
    case SIGUSR2:
        printf("SIGUSR2\n");
        break;
}
}


int main(){
pid_t ids[maxchild];
struct sigaction control;
control.sa_flags=0;
control.sa_handler=sighandler;
sigemptyset(&control.sa_mask);
sigaction(SIGUSR1,&control,NULL);
sigaction(SIGUSR2,&control,NULL);
for(int i=0;i<maxchild;i++){
    ids[i]=fork();
    printf("here %d\n",ids[i]);
    if(ids[i]==0){
        printf("in child\n");
        inchild=i+1;
        break;
    }
}
while(inchild>=0) {
}
    sleep(1);
if(inchild==-1){
    for(int i=0;i<maxchild;i++){
        printf("child: %d\n parent: %d\n",ids[i],getpid());
        kill(ids[i],SIGUSR1);
    }

}
  if (inchild==-1) wait(NULL);
    return 0;
}

that it will work fine

  1. i can comment the "kill(...)" line too to solve the problem:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <sys/time.h>
    #include <wait.h>
    #include <time.h>
    #include <unistd.h>
    #include <signal.h>
    
    #define maxchild 1
    
    int inchild=-1;
    
    void sighandler(int signo){
    char buffer[256];
    int a,b=0;
    switch(signo){
    case SIGUSR1:
        printf("SIGUSR1\n");
        break;
    case SIGUSR2:
        printf("SIGUSR2\n");
        break;
    }
    }
    
    
    int main(){
    pid_t ids[maxchild];
    struct sigaction control;
    control.sa_flags=0;
    control.sa_handler=sighandler;
    sigemptyset(&control.sa_mask);
    sigaction(SIGUSR1,&control,NULL);
    sigaction(SIGUSR2,&control,NULL);
    for(int i=0;i<maxchild;i++){
        ids[i]=fork();
        printf("here %d\n",ids[i]);
        if(ids[i]==0){
            printf("in child\n");
            inchild=i+1;
            break;
        }
    }
    while(inchild>=0) {
    }
     //      sleep(1);
    if(inchild==-1){
        for(int i=0;i<maxchild;i++){
            printf("child: %d\n parent: %d\n",ids[i],getpid());
        //  kill(ids[i],SIGUSR1);
        }
    
    }
      if (inchild==-1) wait(NULL);
        return 0;
    }
    

    now i want to know the reason of problem.

i want to run the first code and see: here (an positive number) here 0 in child child: (an positive number) parent: (an positive number) SIGUSR1 and the program must continue running until i press the Ctrl+c (of course the order of line in output doesn't matter)

i didn't want to change the code, i want to know what is the cause of problem. thank you in advance

1 Answers

1
alk On

If a process has a signal-handler installed this gets called on reception of the signal. This process is not ended then. So all the children are stuck in

  while (inchild >= 0) {
  } 

As no child ends, the parent is blocking in wait().

To fix this replace the above snippet by

  if (inchild >= 0) {
    pause();
  }