Reputation: 29
I have the following code where parent is creating multiple child processes and killing them afterwards. Once killed, I want to print what killed the child (signal in this case). However, the code isnt printing that. what seems to be the problem?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
int i;
static void signal_handler(int signo)
{
if (signo == SIGUSR1)
{
printf("child %d received sigusr1\n", i + 1);
}
}
int main(void)
{
char buff[50];
int status;
if (signal(SIGUSR1, signal_handler) == SIGUSR1)
{
perror("Signal handling error");
}
pid_t cpid, count;
for (i = 0; i < 5; i++)
{
cpid = fork();
if (cpid == 0)
{
sleep(10);
//exit(0);
}
else if (cpid > 0)
{
kill(cpid, SIGUSR1);
int status;
int n = waitpid(cpid, &status, 0);
if (n != cpid)
{
perror("error");
}
if (WIFSIGNALED(status))
{ /* get WTERMSIG(status) */
printf("killed by signal=%d\n", WTERMSIG(status));
}
}
else
{
perror("Fork error: ");
exit(1);
}
}
}
Upvotes: 0
Views: 1027
Reputation: 477110
Use waitpid
instead, and be sure to handle both normal exit and killed-by-signal:
pid_t pid = fork();
if (pid == 0)
{
exit(0);
}
else if (pid > 0)
{
int status;
int n = waitpid(pid, &status, 0);
if (n != pid) { /* error */ }
else if (WIFSIGNALED(status)) { /* get WTERMSIG(status) */ }
else if (WIFEXITED(status)) { /* get WEXITSTATUS(status) */ }
}
else if (pid < 0)
{
/* error */
}
As you can see from the documentation, wait
will wait for any child, not just the current one. And of course its entirely possible that the child exits normally before receiving the signal.
You can stop the child from exiting normally by calling pause
, but the signal will only kill the child if it doesn't get handled. If the signal handler returns, pause
returns, too.
Upvotes: 0
Reputation: 27552
WIFSIGNALED(stat_val) - Evaluates to a non-zero value if status was returned for a child process that terminated due to the receipt of a signal that was not caught
Your signals are being caught (when they are received before they exit).
You have other problems that others have mentioned.
Upvotes: 1
Reputation: 6642
Is this the actual code of your app?
printf("killed by signal=%d\n");
WTERMSIG(status);
If so, the second line has no effect, try changing it to:
printf("killed by signal=%d\n", WTERMSIG(status));
Upvotes: 0