#include #include #include #include #include #include #include #include #include static volatile sig_atomic_t children_left = 0; static void int_to_string(int number, char *buf) { int divisor = 1; int digit_count = 1; int i = 0; while (number / divisor >= 10) { divisor *= 10; digit_count++; } while (digit_count--) { buf[i++] = '0' + (number / divisor); number %= divisor; divisor /= 10; } } static void child_died() { char buf[] = "4294967295"; int total; __sync_fetch_and_sub(&children_left, 1); total = children_left; int_to_string(total, buf); access(buf, R_OK); } int main(int argc __attribute__((__unused__)), char *argv[]) { struct sigaction sa = { 0 }; int wait_time; sigemptyset(&sa.sa_mask); sa.sa_sigaction = child_died; sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_NODEFER | SA_NOCLDSTOP; sigaction(SIGCHLD, &sa, NULL); pid_t pid; char * const args[] = { "/bin/sleep", "1", NULL }; int status = -1; int i; for (i = 0 ; i < 256 ; i++) { status = posix_spawn(&pid, args[0], NULL, NULL, args, NULL); if (status != 0) { fprintf(stderr, "%s: posix_spawn() FAILED, " "status=%d\n", argv[0], status); } else { children_left++; } } wait_time = 3; while (wait_time > 0) { wait_time = sleep(wait_time); } if (children_left != 0) { fprintf(stderr, "%d children didn't notify!\n", children_left); return EXIT_FAILURE; } return EXIT_SUCCESS; }