Home > front end >  Is there a way to execute code in the parent process after the child, which is created using fork an
Is there a way to execute code in the parent process after the child, which is created using fork an

Time:02-25

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
$
  • Related