Skip to main content

Processes and Pipes Lab

Retrieval Prompts

  1. Write the three-step lifecycle of a child process started by a parent: what calls, in what order, in which process?
  2. Explain why fork returns twice, and state the return value in the parent vs the child.
  3. In a shell pipeline A | B, which fd is duped onto which standard fd, in which process?
  4. State the rule for closing pipe ends in the parent. Why does forgetting it hang the downstream process?
  5. Explain the difference between a zombie and an orphan.

Compare and Distinguish

Separate these pairs clearly:

  • fork vs exec
  • exit(0) vs _exit(0)
  • pipe() vs socketpair()
  • dup(fd) vs dup2(fd, 1)
  • waitpid(pid, ...) vs wait(...)

Common Mistake Check

For each snippet, identify the bug:

  1. A child calls exit(1) after a failed execvp, flushing the parent's stdio buffers twice.
  2. A parent forks A | B | C, forgets to close all three pipe ends in itself, and C never sees EOF.
  3. A SIGINT handler calls printf from the main loop's middle.
  4. A program spawns 100 children and never calls waitpid; the process table fills up.
  5. A fork/exec program closes fd 1 in the parent, then opens a file, expecting fd 1 to point at it -- forgetting the child had already inherited the old fd 1.

Mini Application: Build a One-Stage Pipeline

Implement a program runpipe A B that runs A | B as a pipeline. Requirements:

  1. Use pipe, fork, dup2, execvp, waitpid.
  2. Close both pipe ends in the parent before waiting.
  3. Print the exit status of both children.
  4. Fail cleanly if either execvp fails (use _exit(127)).

Verify on runpipe ls 'wc -l' (or with the arguments split).

Mini Application: Zombie Safari

Write a program that forks 5 children. Each sleeps a different number of seconds (1-5), then exits with its index as exit code. The parent must reap all of them in a SIGCHLD handler that loops waitpid(-1, ..., WNOHANG). Demonstrate that no zombies are left at the end (use ps in a second terminal during the run).

Mini Application: Redirection

Write a program that runs ls -l with stdout redirected to out.txt and stderr redirected to err.txt, without using the shell. Close the original fds before exec. Confirm the files contain the expected content.

Scenarios

For each, answer:

  1. Which syscall's failure mode is at issue?
  2. What symptom would the user see?
  3. What is the smallest fix?
  4. What diagnostic tool would confirm the fix?

Scenarios:

  1. A shell pipeline cmd | grep foo completes cmd but grep hangs indefinitely.
  2. A server forks per connection, runs for a week, and ps shows thousands of <defunct> entries.
  3. A daemon's Ctrl-C handler sets a flag, but the daemon never exits because the main loop is blocked in read.
  4. A subprocess library deadlocks because it forgot FD_CLOEXEC and the exec'd program inherits a pipe neither side closes.
  5. A child process inherits a stdout FILE * from the parent, forks, both call printf, and the same line appears twice on screen.

Evidence Check

This lab is complete when you can, for each scenario, say which syscall sequence produced the symptom and what strace -f would show.