Skip to content

Instantly share code, notes, and snippets.

@ridiculousfish
Created May 11, 2020 20:03
Show Gist options
  • Save ridiculousfish/4751663796b7a99a4293ed2359fe2d57 to your computer and use it in GitHub Desktop.
Save ridiculousfish/4751663796b7a99a4293ed2359fe2d57 to your computer and use it in GitHub Desktop.
#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