💾 Archived View for thrig.me › blog › 2023 › 06 › 14 › sometimes.c captured on 2024-05-10 at 12:24:01.

View Raw

More Information

⬅️ Previous capture (2023-06-14)

-=-=-=-=-=-=-

#include <sys/wait.h>

#include <err.h>
#include <stdlib.h>
#include <unistd.h>

#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);
}