I am trying to send a child's pid to his father using SIGUSR1 and sigqueue. But the signal is never sent, or it appears not to be sent.
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <stdlib.h>
void handler(int signum, siginfo_t *info, void *extra)
{
void *ptr_val = info->si_value.sival_ptr;
int int_val = info->si_value.sival_int;
printf("Child: Father, I am %d!\n",int_val);
}
int main()
{
int pid;
printf("Father: I am %d\n",getpid());
if ( (pid=fork()) <0 )
{
perror("fork");
exit(EXIT_FAILURE);
}
else
if ( pid==0 )
{
printf("Child: I am My father is %d.\n",getppid());
sigqueue(getppid(),SIGUSR1,(const union sigval) getpid());
}
else
{
struct sigaction action;
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask,SIGUSR1);
action.sa_flags = SA_SIGINFO;
action.sa_mask =mask;
action.sa_sigaction = &handler;
if (sigaction(SIGUSR1,&action,NULL)==-1)
{
perror("sigaction");
exit(EXIT_FAILURE);
}
printf("Father: Welcome home, son!\n");
}
return 0;
}
Running the code above I get the following output:
Father: I am 18990
Father: Welcome home, son!
Child: My father is 18990.
And that's not all. If I run it again, all my apps close(editor,terminal,etc.) and I need to sign in again. (kind of a switch user operation) What's wrong with the code? Thanks.
The reason the signal is not caught is that parent is exiting before the child queues up the signal. Just add a delay inside the parent and you can see that it catches the signal.
This fact is further strengthened by a different output that I get on my system for your same program
The child notes the father's pid as 1, because the father has exited leaving the child as orphan and being adopted by init.
A very related question
getpid and getppid returns two different values