The Missing EOF

This program is supposed to capture the output of echo hello and print it, then exit. It prints hello and then hangs forever.

int fd[2];
pipe(fd);

if (fork() == 0) {
    close(fd[0]);
    dup2(fd[1], STDOUT_FILENO);
    close(fd[1]);
    execlp("echo", "echo", "hello", NULL);
    _exit(127);
}

char buf[256];
ssize_t n;
while ((n = read(fd[0], buf, sizeof buf)) > 0)
    write(STDOUT_FILENO, buf, n);

wait(NULL);

Why does it hang, and what is the fix?

A

The 256-byte buffer is smaller than the 65,536-byte pipe capacity, so read waits for a full pipe. Enlarge buf to PIPE_BUF

B

The parent never closed fd[1], so a write end is still open and read never returns 0. Add close(fd[1]); in the parent before the read loop

C

The parent never closed fd[1], so write on the pipe is blocking. Set O_NONBLOCK on fd[1]

D

wait(NULL) is unreachable because echo never exits. Reap the child with waitpid(..., WNOHANG) inside the loop instead