I am having a parent process play
that creates a fork and runs foo
using execl
Code for play.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
if (fork() == 0) {
execl("./foo", "", NULL);
} else {
wait(0);
write(STDOUT_FILENO, "in parent after waiting", 5);
}
printf("outside everything");
return 0;
}
Code for foo.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void signal_handler() {
write(STDOUT_FILENO, "\nBye!\n", 6);
exit(1);
}
int main() {
struct sigaction sa;
sa.sa_handler = signal_handler;
sigaction(SIGINT, &sa, NULL);
while (1) {
printf("Wasting time...%d \n", getpid());
sleep(1);
}
return 0;
}
My questions are,
- Why aren't the print statements after the
wait(0)
statement executed? - Why isn't the signal handler in the child process triggered when Ctrl C?
CodePudding user response:
You should ensure that the sa_flags
and sa_mask
fields of struct sigaction
are set. You can initialize them — struct sigaction sa = { 0 };
will probably do the job. Or you can use sigemptyset(&sa.sa_mask);
and sa.sa_flags = 0;
to assign values. Or you can set them to some non-zero value. Not setting sa_flags
means you've no idea what operation you requested. You also need a signal handler in play.c
. You need to ignore SIGINT
before the fork()
, then in the child re-enable the signal before executing foo
. The write()
in the parent does not print much; it may once have printed "\nBar!\n"
or something.
Here's some working code.
play.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
struct sigaction sa = { 0 };
sa.sa_handler = SIG_IGN;
sigaction(SIGINT, &sa, NULL);
if (fork() == 0)
{
sa.sa_handler = SIG_DFL;
sigaction(SIGINT, &sa, NULL);
execl("./foo", "", NULL);
exit(1);
}
else
{
wait(0);
printf("in parent after waiting\n");
}
printf("outside everything\n");
return 0;
}
foo.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void signal_handler(int signum)
{
char message[] = "\nBye (XX)\n";
message[6] = signum / 10 '0';
message[7] = signum % 10 '0';
write(STDOUT_FILENO, message, sizeof(message) - 1);
exit(1);
}
int main(void)
{
struct sigaction sa = { 0 };
sa.sa_handler = signal_handler;
sigaction(SIGINT, &sa, NULL);
while (1)
{
printf("Wasting time...%d \n", getpid());
sleep(1);
}
return 0;
}
Example output
$ play
Wasting time...11383
Wasting time...11383
Wasting time...11383
Wasting time...11383
^C
Bye (02)
in parent after waiting
outside everything
$