I am trying to use signals to pass between a parent and child process, but after the first 2 statements are printed (for example in mine it shows CHILD 0: Running, parent is 4224 PARENT 4224: Telling the Child Process 4225 to start) it just gets stuck running forever! I'm not sure where I am going wrong on this...but any pointers to where I run astray would be appreciated!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
void p_sig_usr(int signo){
if(signo == SIGUSR1){
printf("*** Parent SIGUSR1 handler - Received 'task started' signal from child ***\n");
}
if(signo == SIGUSR2){
printf("*** Parent SIGUSR2 handler - Received 'task completed' signal from child ***\n");
}
else
printf("unexpected signal received");
return;
}
void c_sig_usr(int signo){
if(signo == SIGUSR1){
printf("*** Child SIGUSR1 handler - Received 'task start' signal from parent ***\n");
}
if(signo == SIGUSR2){
printf("*** Child SIGUSR2 handler - Received 'task complete verification' signal from parent ***\n");
}
else
printf("unexpected signal received");
return;
}
int main(void)
{
pid_t child_pid, parent_pid;
parent_pid = getpid();
struct sigaction p_sig;
sigemptyset(&p_sig.sa_mask);
p_sig.sa_flags = 0;
p_sig.sa_handler = p_sig_usr;
child_pid = fork();
if ( child_pid == -1){
perror("failed to fork a new process");
return 1;
}
if (child_pid == 0){
struct sigaction c_sig;
sigset_t c_myset;
sigemptyset(&c_sig.sa_mask);
c_sig.sa_flags = 0;
c_sig.sa_handler = c_sig_usr;
printf("CHILD %d: Running, parent is %d\n",child_pid, parent_pid);
sigfillset(&c_myset);
sigdelset(&c_myset, SIGUSR1);
sigsuspend(&c_myset);//suspend until get SIGUSR1
printf("CHILD: Telling parent that I'm starting task.\n");
sleep(3);
kill(parent_pid, SIGUSR1);
printf("CHILD: Performing task\n");
sigfillset(&c_myset);
sigdelset(&c_myset, SIGUSR2);
sigsuspend(&c_myset);//suspend and wait for SIGUSR2
printf("CHILD: Telling parent that work is done.\n");
kill(parent_pid, SIGUSR2);
printf("CHILD %d: Finished\n", child_pid);
}
else{
struct sigaction p_sig;
sigset_t p_myset;
sigemptyset(&p_myset);
sleep(3);//parent now sleeping to let child set up handlers
printf("PARENT %d: Telling the Child Process %d to start\n", parent_pid, child_pid);
kill(child_pid, SIGUSR1);
sigfillset(&p_myset);
sigdelset(&p_myset, SIGUSR1);
sigsuspend(&p_myset);//suspend until get SIGUSR1
sleep(3);
kill(child_pid,SIGUSR2);
printf("PARENT: Told child to notify of task completion.\n");
sigfillset(&p_myset);
sigdelset(&p_myset, SIGUSR2);//suspend until get SIGUSR2
printf("PARENT %d: Finished.", parent_pid);
}
return 0;
}
|
Output I was hoping to achieve with this program is as follows:
CHILD 529: Running, parent is 528.
PARENT 528: Telling child 529 to start.
*** Child SIGUSR1 handler - Received 'task start' signal from parent ***
CHILD: Telling parent that I'm starting task.
CHILD: Performing task.
*** Parent SIGUSR1 handler - Received 'task started' signal from child ***
PARENT: Told child to notify of task completion.
*** Child SIGUSR2 handler - Received 'task complete verification' signal from parent ***
CHILD: Telling parent that work is done.
CHILD 529: Finished.
*** Parent SIGUSR2 handler - Received 'task completed' signal from child ***
PARENT 528: Finished.
Thank you in advance for your help!