Created
May 11, 2020 20:03
-
-
Save ridiculousfish/4751663796b7a99a4293ed2359fe2d57 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <fcntl.h> | |
#include <limits.h> | |
#include <signal.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <sys/wait.h> | |
#include <sys/time.h> | |
static int pipes[2]; | |
static void assert_noerr(int res) | |
{ | |
if (res < 0) | |
{ | |
fprintf(stderr, "error: %s", strerror(res)); | |
exit(EXIT_FAILURE); | |
} | |
} | |
static void sigchld_handler(int sig) | |
{ | |
// Write a byte to the write end of pipes. | |
(void)sig; | |
char c = 0; | |
ssize_t amt = write(pipes[1], &c, 1); | |
if (amt < 0) | |
{ | |
perror("write"); | |
exit(EXIT_FAILURE); | |
} | |
} | |
static void make_fd_nonblocking(int fd) | |
{ | |
int flags = fcntl(fd, F_GETFL, 0); | |
assert_noerr(flags); | |
assert_noerr(fcntl(fd, F_SETFL, flags | O_NONBLOCK)); | |
} | |
static pid_t spawn_child() | |
{ | |
pid_t pid = fork(); | |
assert_noerr(pid); | |
if (pid == 0) | |
{ | |
_exit(0); | |
} | |
return pid; | |
} | |
int main(void) | |
{ | |
// Install SIGCHLD handler with SA_RESTART. | |
struct sigaction chld_act = {}; | |
sigemptyset(&chld_act.sa_mask); | |
chld_act.sa_handler = &sigchld_handler; | |
chld_act.sa_flags = SA_RESTART; | |
assert_noerr(sigaction(SIGCHLD, &chld_act, NULL)); | |
// Make our self-pipes. | |
assert_noerr(pipe(pipes)); | |
// Spawn and reap children in a loop. | |
unsigned count = 0; | |
for (;;) | |
{ | |
// Spawn a child. | |
pid_t child = spawn_child(); | |
assert(child >= 0 && "Invalid pid"); | |
// Wait for the SIGCHLD handler to write to us. | |
for (;;) | |
{ | |
char buf[PIPE_BUF]; | |
ssize_t amt = read(pipes[0], buf, sizeof buf); | |
if (amt >= 0) | |
break; | |
} | |
// Reap it. | |
int status = 0; | |
int pid_res = waitpid(child, &status, WUNTRACED | WCONTINUED); | |
assert(pid_res == child && "Unexpected pid"); | |
if ((++count % 256) == 0) | |
fprintf(stdout, "%u\n", count >> 8); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment