Last active
August 3, 2016 20:37
-
-
Save gmacon/e4ff879beaf9a2e3e607fc596dd16c91 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
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 |
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 <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