sir chen
sir chen

Reputation: 21

why does my program get stuck in wait(NULL)?

I'm a c beginner and wrote a multiprocess program. I want to let my child process invoke strace and then pipe to the parent process so that parent process could print it.

But my parent progress seem to be getting stuck in wait(NULL); . I tried commenting code wait(NULL); and I got the output from my child process. I can't figure out why parent process keeping waiting. Hasn't the child process returned yet?

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char *argv[]) {
  int pipefd[2];
  pid_t pid;
  char *exec_argv[] = { "/bin/strace", "-T", "tree", "/bin", NULL};
  char *exec_envp[] = { "PATH=/bin", NULL };

  if (pipe(pipefd) == -1) {
    perror("pipe");
    exit(EXIT_FAILURE);
  }
  pid = fork();
  if (pid < 0) {
    perror("fork");
    exit(EXIT_FAILURE);
  } else if (pid == 0) { // child
    close(pipefd[0]);   /* close unused read end */
    close(STDOUT_FILENO);
    if (dup2(pipefd[1], STDERR_FILENO) == -1) {
      perror("dup2");
      exit(EXIT_FAILURE);
    }
    // invoke strace
    execve(exec_argv[0], exec_argv, exec_envp);
    perror(exec_argv[0]);
    exit(EXIT_FAILURE);
  } else {  // parent
    close(pipefd[1]);   /* close unused write end */
    if (dup2(pipefd[0], STDIN_FILENO) == -1) {
      perror("dup2");
      exit(EXIT_FAILURE);
    }
    printf("I'm parent!!!\n");
    wait(NULL);
    char *line = NULL;
    size_t len;
    while (getline(&line, &len, stdin) != -1) {
      printf("%s", line);
    }
    free(line);
  }
  return 0;
}

Upvotes: 0

Views: 184

Answers (1)

ikegami
ikegami

Reputation: 386351

You didn't close pipefd[0] in the parent.

You didn't close pipefd[1] in the child.


Another problem is that your code is susceptible to deadlocks. If the child writes enough to the pipe to fill it, it will block until it has space to accept more. And since the the pipe is not emptied until the child exits, the child will never unblock.

This is easy to fix: Read until EOF, then call wait to reap the child. In other words, move the wait so it's after the loop.

Upvotes: 1

Related Questions