I am trying to send a signal from a child process to a parent process in C, and I've got a signal handler setup:
void handler(int signumber,siginfo_t* info,void* nonused)
{
printf("Signal with number %i has arrived\n",signumber);
switch (info->si_code){
case SI_USER: printf("Process (PID number %i) sent the signal (calling kill)\n",info->si_pid); break;
case SI_TIMER: printf("It was sent by a timer\n");
printf("Additional data: %i\n",info->si_value.sival_int);
// timer_delete(t_id); //stops timer
break;
case SI_QUEUE: printf("It was sent by a sigqueue, sending process (PID %i)\n",info->si_pid);
printf("Additional value: %i\n",info->si_value.sival_int);
// struct student* d=(struct student*)info->si_value.sival_ptr;
// printf("Additional value: %s, %i\n",d->name,d->year);
break;
default: printf("It was sent by something else \n");
}
}
And the attempt to send a signal with additional data using sigqueue:
struct sigaction action;
action.sa_sigaction = handler;
sigemptyset(&action.sa_mask);
action.sa_flags=SA_SIGINFO;
if (sigaction(SIGTERM, &action, NULL) < 0)
{
perror("Sigaction failed");
exit(1);
}
pid = fork();
if (pid == -1)
{
perror("Forking error");
exit(EXIT_FAILURE);
}
if (pid == 0) //child process
{
printf("Child process (PID %i), will send a SIGTERM to parent %i\n",getpid(),getppid());
// sleep(1);
// kill(getppid(),SIGTERM); //this works
//sending an integer as an additional data
sleep(1);
union sigval s_value_int={5};
sigqueue(getppid(),SIGTERM,s_value_int);
printf("Child process ended\n");
}
else
{
printf("Parent (PID %i) waits for a signal from child (PID %i) \n",getpid(),pid);
pause();
wait(NULL);
printf("Parent process ended\n");
}
The problem is, I am not receiving any kind of output (from the handler) and the parent process freezes forever (waiting for the signal from the child because of the pause()
call), therefore I suspect that the signal never arrives. "Child process ended" gets output to the console.
Interestingly, if I send the signal via kill()
, the parent receives it just fine and the handler prints out the additional info too. Unfortunately I need the sigqueue alternative, because I must send an additional integer as data to the parent. I read about possible signal losses because of too many signals coming in and they get queued up, could that be the problem in my case too? If so, what could be done to fix it?
Many thanks