2

I am reading the book Advanced Programming in the Unix Environment. There is a test program to test the fork function. It works well in my Ubuntu. But what I confused is that why there is no command indicator prompt after the child process exits. The original program is like the below.

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

int main()
{
  pid_t pid;
  if ((pid = fork()) < 0)
  {
    printf("fork error.\n");
    return 1;
  }
  else if (pid == 0)
  {
    if ((pid = fork()) < 0)
    {
      printf("fork error.\n");
      return 1;
    }
    else if (pid > 0)
    {
      printf("first child %d exit.\n", getpid());
      exit(0);
    }
    sleep(2);
    printf("second child %d has parent pid = %d.\n",getpid(),  getppid());
    exit(0);
  }

  printf("waitid %d.\n", pid);
  if (waitpid(pid, NULL, 0) != pid)
  {
    printf("waitid error.\n");
    return 1;
  }
  printf("process %d will exit..\n", getpid());

  exit(0);
}

Then I run

jerryli@ubuntu:~/project/unix$ ./p183.o
waitid 2256
first child 2256 exit.
process 2255 will exit..
jerryli@ubuntu:~/project/unix$ second child 2257 has parent pid = 1.

After above line prompt, there is nothing continue. I expect it would show

jerryli@ubuntu:~/project/unix$

In order to have above indicator, I have to type Enter.

Could you know the reason? Is that because the second child's parent process becomes the system init process?

3

fork starts a process in the background. When the foreground process (the one that calls fork) terminates, the calling shell is notified, and it shows a new prompt. The shell is the parent of the original, foreground process; it's not the parent of either forked process.

The order in which the original process and the forked process execute is not fixed, but it's unlikely to deviate in any relevant way due to the 2-second delay. In your test, it so happens that the timeline was:

  1. fork the first child from the original process.
  2. fork the second child from the first child.
  3. The original process prints the waitid trace and starts the waitpid call to wait for the first child.
  4. The first child prints its exit trace, and exits.
  5. The original process is notified of the child process's death, and its waitpid call returns.
  6. The original process prints its will exit trace.
  7. The shell is notified that the original process exited and prints its prompt.
  8. A little under 2 seconds later, the sleep call in the second child completes, and the second child prints its has parent trace.

The shell doesn't get any notification whatsoever of that last event, because it's not the parent of the dying process. In any case, it's already displayed a prompt and is waiting for you to enter a new command; it would have no reason to do anything (if you were typing a command, that could be disruptive).

0

Following @Gilles answer, I amanged to achieve a similar thing to what @jerry asked by 1. storing terminals PID before forking 2. sending SIGINT after each set of print's to "nudge" the terminal to display the prompt

dirty, but it seems to do the job

New contributor
trekski is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
  • This seems to be a comment on another answer. – RalfFriedl 2 days ago

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.