#include #include #include #include #define IS_CHILD(x) !(x) #define PIPE_READER 0 #define PIPE_WRITER 1 int main(void) { int epipe[2]; if (pipe(epipe) == -1) err(1, "pipe"); pid_t pid = fork(); if (pid < 0) err(1, "fork"); if (IS_CHILD(pid)) { close(epipe[PIPE_READER]); if (epipe[PIPE_WRITER] != STDERR_FILENO) { if (dup2(epipe[PIPE_WRITER], STDERR_FILENO) != STDERR_FILENO) err(1, "dup2"); close(epipe[PIPE_WRITER]); } // non-boilerplate child code: emit to standard error // and sometimes exit with a non-zero exit status word warnx("wolf wolf wolf"); if (arc4random_uniform(2)) { warnx("Wolf!"); exit(1); } exit(0); } close(epipe[PIPE_WRITER]); int status; wait(&status); if (status) { char buf[42]; while (1) { ssize_t ret = read(epipe[PIPE_READER], buf, 42); if (ret == 0) break; // EOF if (ret < 0) err(1, "read"); write(STDERR_FILENO, buf, (size_t) ret); } exit(1); } exit(0); }