Reputation: 526
In the main process I listen to SIGCHLD:
signal(SIGCHLD, &my_handler);
Then I fork()
, execv()
and let it run in background (/bin/cat for example).
When I try from terminal to send SIGSTOP to the child process, my_handler()
gets called. But when I try to send SIGCONT to it, the the handler isn't called on macOS but it's executed on my Ubuntu.
Man:
SIGCHLD: child status has changed.
Am I missing something? Is it an expected behaviour? I wrote my app on Ubuntu and expected it to work on mac as well.
I tried with sigaction()
as well, but with the same results.
Here's a sample code to demonstrate:
#include <signal.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
void my_handler(int signum)
{
printf("\t SIGCHLD received\n");
fflush(stdout);
}
void my_kill(pid_t pid, int signum)
{
printf("Sending %d\n", signum);
fflush(stdout);
kill(pid, signum);
printf("Sent %d\n\n", signum);
fflush(stdout);
}
int main()
{
pid_t pid;
char *cat_args[2] = {"/bin/cat", NULL};
signal(SIGCHLD, &my_handler);
pid = fork();
if (pid == 0)
{
execv("/bin/cat", cat_args);
}
else
{
my_kill(pid, SIGSTOP);
my_kill(pid, SIGCONT);
wait(NULL);
}
return 0;
}
With the output on macOS:
Sending 17
SIGCHLD received
Sent 17
Sending 19
Sent 19
Upvotes: 2
Views: 1364
Reputation: 58524
That behavior is optional. An implementation need not generate a SIGCHLD upon continuation. The language used in POSIX.1-2008 (2016 edition) is "may" rather than "shall":
When a stopped process is continued, a SIGCHLD signal may be generated for its parent process, unless the parent process has set the SA_NOCLDSTOP flag.
- System Interfaces, 2.4.3 Signal Actions
...a SIGCHLD signal may be generated for the calling process whenever any of its stopped child processes are continued.
-
System Interfaces sigaction
"Description"
Emphases added.
Upvotes: 5
Reputation: 70883
Am I missing something?
Probably not.
Is it an expected behaviour?
Probably yes.
OSX is based on 4.4 BSD, and this BSD simply does not support sending a SIGCHLD
to the parent when the child continues. Earlier versions of Linux lacked this support as well.
Upvotes: 3