Skip to content

Instantly share code, notes, and snippets.

@gmacon
Last active August 3, 2016 20:37
Show Gist options
  • Save gmacon/e4ff879beaf9a2e3e607fc596dd16c91 to your computer and use it in GitHub Desktop.
Save gmacon/e4ff879beaf9a2e3e607fc596dd16c91 to your computer and use it in GitHub Desktop.
forked child with pid 7505 master fd is 3, 1 outstanding
forked child with pid 7506 master fd is 4, 2 outstanding
forked child with pid 7507 master fd is 5, 3 outstanding
forked child with pid 7508 master fd is 6, 4 outstanding
forked child with pid 7509 master fd is 7, 5 outstanding
forked child with pid 7510 master fd is 8, 6 outstanding
forked child with pid 7511 master fd is 9, 7 outstanding
forked child with pid 7512 master fd is 10, 8 outstanding
forked child with pid 7513 master fd is 11, 9 outstanding
forked child with pid 7514 master fd is 12, 10 outstanding
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/select.h>
#include <strings.h>
#include <unistd.h>
#include <util.h>
volatile sig_atomic_t got_sigchld = 0;
void sigchld_handler(int sig) {
got_sigchld = 1;
}
struct childinfo {
pid_t pid;
int amaster;
};
int main(int argc, char **argv) {
sigset_t sigmask_block;
sigset_t sigmask_empty;
fd_set to_read;
int fd_max;
int outstanding_children = 0;
int children_to_create = 10;
struct childinfo kids[10];
bzero(&kids, sizeof(kids));
int amaster = -1;
pid_t pid;
sigemptyset(&sigmask_empty);
sigemptyset(&sigmask_block);
sigaddset(&sigmask_block, SIGCHLD);
sigprocmask(SIG_BLOCK, &sigmask_block, NULL);
struct sigaction sa;
bzero(&sa, sizeof(sa));
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sa.sa_handler = sigchld_handler;
sigaction(SIGCHLD, &sa, NULL);
while (children_to_create-- > 0) {
if (!(pid = forkpty(&amaster, NULL, NULL, NULL))) {
return 0;
} else if (pid < 0) {
perror("fork");
} else {
outstanding_children++;
printf("forked child with pid %d master fd is %d, %d outstanding\n", pid, amaster, outstanding_children);
kids[children_to_create].pid = pid;
kids[children_to_create].amaster = amaster;
}
}
do {
FD_ZERO(&to_read);
fd_max = 0;
for (int i = 0; i < 10; ++i) {
if (kids[i].pid) {
FD_SET(kids[i].amaster, &to_read);
if (kids[i].amaster >= fd_max) {
fd_max = kids[i].amaster + 1;
}
}
}
pselect(fd_max, &to_read, NULL, NULL, NULL, &sigmask_empty);
if (got_sigchld) {
printf("got_sigchld\n");
while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
outstanding_children--;
printf("waited child %d, %d outstanding\n", pid, outstanding_children);
for (int i = 0; i < 10; ++i) {
if (kids[i].pid == pid) {
close(kids[i].amaster);
break;
}
}
}
if (pid < 0) {
perror("waitpid");
}
got_sigchld = 0;
}
} while(outstanding_children);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment