#include #include #include #include #include #include #include #include #include #include #include #if !defined(WITH_SIGCHLD) #define WITH_SIGCHLD 1 #endif #if WITH_SIGCHLD == 1 /* * vsftpd * sysutil.c vsf_sysutil_wait_reap_one() * standalone.c handle_sigchld() * */ int vsf_sysutil_wait_reap_one(void) { int retval = waitpid(-1, NULL, WNOHANG); if (retval == 0 || (retval < 0 && errno == ECHILD)) { /* No more children */ return 0; } if (retval < 0) { perror("waitpid"); exit(EXIT_FAILURE); } /* Got one */ return retval; } int received; int reaped; void handle_sigchld(int sig) { unsigned int reap_one = 1; received++; while (reap_one) { reap_one = (unsigned int) vsf_sysutil_wait_reap_one(); if (reap_one) reaped++; } } #endif int zombies; int main(int argc, char *argv[]) { int i, ret; #if WITH_SIGCHLD == 1 /* * vsftpd sysutil.c vsf_sysutil_set_sighandler() */ struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = handle_sigchld; if (-1 == sigfillset(&sa.sa_mask)) { perror("sigfillset"); exit(EXIT_FAILURE); } if (-1 == sigaction(SIGCHLD, &sa, NULL)) { perror("sigaction"); exit(EXIT_FAILURE); } fprintf(stderr, "SIGCHLD handler enabled\n"); #else fprintf(stderr, "SIGCHLD handler not enabled\n"); #endif for (i = 0; i < 100; i++) { // if (0 == (ret = syscall(__NR_clone, CLONE_NEWPID | CLONE_NEWIPC | CLONE_NEWNET | CLONE_NEWUSER | SIGCHLD, NULL))) if (0 == (ret = syscall(__NR_clone, CLONE_NEWPID | SIGCHLD, NULL))) return 0; if (-1 == ret) { perror("clone"); exit(EXIT_FAILURE); } } #if 1 while (1) { int res = waitpid(-1, NULL, WNOHANG); if (res < 0) break; if (!res) continue; zombies++; } // printf("received %d signals, reaped %d - %d zombies left\n", received, reaped, zombies); // sleep(1); #endif return 0; }