#define _GNU_SOURCE #include #include #include #include #include #include #include int pipefd[2]; int init(void *arg) { int nr, i, err; sighandler_t sigret; char c; close(pipefd[0]); err = setsid(); if (err < 0) { perror("setsid"); abort(); } sigret = signal(SIGCHLD, SIG_IGN); if (sigret == SIG_ERR) { fprintf(stderr, "signal\n"); abort(); } nr = atoi(arg); for (i = 0; i < nr; i++) { err = fork(); if (err < 0) { perror("fork"); abort(); } else if (err == 0) { printf("%d before\n", getpid()); fflush(stdout); pause(); printf("%d after\n", getpid()); fflush(stdout); return 0; } } err = write(pipefd[1], &c, 1); if (err != 1) { perror("write"); abort(); } pause(); return 0; } int main(int argc, char *argv[]) { long stack_size = sysconf(_SC_PAGESIZE); void *stack = alloca(stack_size) + stack_size; pid_t pid; char c; int ret; ret = pipe(pipefd); if (ret) { perror("pipe"); abort(); } ret = clone(init, stack, CLONE_NEWPID | SIGCHLD, argv[1]); if (ret < 0) { perror("clone"); abort(); } pid = ret; printf("%d\n", pid); fflush(stdout); close(pipefd[1]); ret = read(pipefd[0], &c, 1); if (ret != 1) { if (ret) { perror("read"); abort(); } else { sleep(5); } } printf("killing %d\n", pid); fflush(stdout); ret = kill(-pid, SIGKILL); if (ret) { perror("kill"); abort(); } return 0; }