int mod_forkbomb(int argc,char *argv[]) { ssize_t n = argc > 2 ? atoi(argv[2]) : 100; ssize_t i = 0; while(1) { pids[i] = fork(); /* the childs break here */ if(pids[i] == 0) break; /* failed? so send all created child-procs the kill-signal */ if(i >= n || pids[i] < 0) { if(pids[i] < 0) printe("fork() failed"); printf("Kill all childs\n"); fflush(stdout); while(i >= 0) { if(pids[i] > 0) { if(kill(pids[i],SIGKILL) < 0) perror("kill"); waitchild(NULL,-1); } i--; } return 0; } i++; } sleep(10000); return 0; }
int system(const char *cmd) { int child; sExitState state; /* check whether we have a shell */ if(cmd == NULL) { int fd = open("/bin/shell",O_RDONLY); if(fd >= 0) { close(fd); return EXIT_SUCCESS; } return EXIT_FAILURE; } child = fork(); if(child == 0) { const char *args[] = {"/bin/shell","-e",NULL,NULL}; args[2] = cmd; execv(args[0],args); /* if we're here there is something wrong */ error("Exec of '%s' failed",args[0]); } else if(child < 0) error("Fork failed"); /* wait and return exit-code */ if((child = waitchild(&state,-1)) < 0) return child; return state.exitCode; }
pid_t waitpid(pid_t pid,int *stat_loc,A_UNUSED int options) { sExitState state; int res = waitchild(&state,pid); if(res < 0) return res; *stat_loc = (state.exitCode & 0xFF) | (state.signal << 8); return state.pid; }
int main(int argc,char **argv) { uint64_t start,end; char path[MAX_PATH_LEN + 1] = "/bin/"; if(argc < 2 || isHelpCmd(argc,argv)) usage(argv[0]); strcat(path,argv[1]); if(signal(SIGINT,sigHdlr) == SIG_ERR) error("Unable to set sig-handler for signal %d",SIGINT); start = rdtsc(); if((waitingPid = fork()) == 0) { size_t i; const char **args = (const char**)malloc(sizeof(char*) * (argc - 1)); if(!args) error("Not enough mem"); for(i = 1; i < (size_t)argc; i++) args[i - 1] = argv[i]; args[argc - 1] = NULL; execvp(args[0],args); error("Exec failed"); } else if(waitingPid < 0) error("Fork failed"); else { sExitState state; int res; while(1) { res = waitchild(&state,-1); if(res != -EINTR) break; } end = rdtsc(); if(res < 0) error("Wait failed"); fprintf(stderr,"\n"); fprintf(stderr,"Process %d (%s) terminated with exit-code %d\n",state.pid,path,state.exitCode); if(state.signal != SIG_COUNT) fprintf(stderr,"It was terminated by signal %d\n",state.signal); fprintf(stderr,"Runtime: %Lu us\n",state.runtime); fprintf(stderr,"Realtime: %Lu us\n",tsctotime(end - start)); fprintf(stderr,"Scheduled: %lu times\n",state.schedCount); fprintf(stderr,"Syscalls: %lu\n",state.syscalls); fprintf(stderr,"Migrations: %lu\n",state.migrations); fprintf(stderr,"Own mem: %lu KiB\n",state.ownFrames * 4); fprintf(stderr,"Shared mem: %lu KiB\n",state.sharedFrames * 4); fprintf(stderr,"Swapped: %lu KiB\n",state.swapped * 4); } return EXIT_SUCCESS; }
int mod_sigclone(A_UNUSED int argc,A_UNUSED char *argv[]) { int res; parent = getpid(); if(signal(SIGINT,sigint) == SIG_ERR) error("Unable to set sighandler"); if((child = fork()) == 0) { printf("Please give me a SIGINT!\n"); fflush(stdout); sleep(1000000); printf("Child got %d signals\n",childCount); exit(EXIT_SUCCESS); } /* parent waits */ do { res = waitchild(NULL,-1); } while(res == -EINTR); printf("Parent got %d signals\n",parentCount); return 0; }
void forkfiles(char ficheros[][128],int txtfiles,int bytes){ int i; int pid; struct stat fichero; for(i=0;i<txtfiles;i++){ pid = fork(); switch(pid){ case -1: err(1,"Error: fork \n"); break; case 0: stat(ficheros[i],&fichero); if ((fichero.st_size)<bytes) bytes = fichero.st_size; creatfile(ficheros[i],bytes); exit(EXIT_SUCCESS); break; } } waitchild(txtfiles); }
/* * Test basic select functionality on /dev/tty. While this test should not be * part of this test set, we already have all the infrastructure we need here. */ static void test77f(void) { struct sigaction act, oact; char c, pname[PATH_MAX], tname[PATH_MAX]; struct timeval tv; fd_set fd_set; int fd, maxfd, masterfd, slavefd; subtest = 6; /* We do not want to get SIGHUP signals in this test. */ memset(&act, 0, sizeof(act)); act.sa_handler = SIG_IGN; if (sigaction(SIGHUP, &act, &oact) < 0) e(1); /* Get master and slave device names for a free pseudo terminal. */ get_names(pname, tname); if ((masterfd = open(pname, O_RDWR | O_NOCTTY)) < 0) e(2); switch (fork()) { case 0: if (setsid() < 0) e(3); close(masterfd); if ((slavefd = open(tname, O_RDWR)) < 0) e(4); if ((fd = open("/dev/tty", O_RDWR)) < 0) e(5); make_raw(fd); /* Without slave input, /dev/tty is not ready for reading. */ FD_ZERO(&fd_set); FD_SET(fd, &fd_set); tv.tv_sec = 0; tv.tv_usec = 0; if (select(fd + 1, &fd_set, NULL, NULL, &tv) != 0) e(6); if (FD_ISSET(fd, &fd_set)) e(7); FD_SET(fd, &fd_set); tv.tv_sec = 0; tv.tv_usec = 10000; if (select(fd + 1, &fd_set, NULL, NULL, &tv) != 0) e(8); if (FD_ISSET(fd, &fd_set)) e(9); /* It will be ready for writing, though. */ FD_SET(fd, &fd_set); if (select(fd + 1, NULL, &fd_set, NULL, NULL) != 1) e(10); if (!FD_ISSET(fd, &fd_set)) e(11); /* Test mixing file descriptors to the same terminal. */ FD_ZERO(&fd_set); FD_SET(fd, &fd_set); FD_SET(slavefd, &fd_set); tv.tv_sec = 0; tv.tv_usec = 10000; maxfd = fd > slavefd ? fd : slavefd; if (select(maxfd + 1, &fd_set, NULL, NULL, &tv) != 0) e(12); if (FD_ISSET(fd, &fd_set)) e(13); if (FD_ISSET(slavefd, &fd_set)) e(14); /* The delayed echo on the master must wake up our select. */ c = 'A'; if (write(slavefd, &c, sizeof(c)) != sizeof(c)) e(15); FD_ZERO(&fd_set); FD_SET(fd, &fd_set); if (select(fd + 1, &fd_set, NULL, NULL, NULL) != 1) e(16); if (!FD_ISSET(fd, &fd_set)) e(17); /* Select must now still flag readiness for reading. */ tv.tv_sec = 0; tv.tv_usec = 0; if (select(fd + 1, &fd_set, NULL, NULL, &tv) != 1) e(18); if (!FD_ISSET(fd, &fd_set)) e(19); /* That is, until we read the byte. */ if (read(slavefd, &c, sizeof(c)) != sizeof(c)) e(20); if (c != 'B') e(21); if (select(fd + 1, &fd_set, NULL, NULL, &tv) != 0) e(22); if (FD_ISSET(fd, &fd_set)) e(23); /* Ask the parent to close the master. */ c = 'C'; if (write(slavefd, &c, sizeof(c)) != sizeof(c)) e(24); FD_SET(fd, &fd_set); /* The closure must cause an EOF condition on the slave. */ if (select(fd + 1, &fd_set, NULL, NULL, NULL) != 1) e(25); if (!FD_ISSET(fd, &fd_set)) e(26); if (select(fd + 1, &fd_set, NULL, NULL, NULL) != 1) e(27); if (!FD_ISSET(fd, &fd_set)) e(28); if (read(slavefd, &c, sizeof(c)) != 0) e(29); exit(errct); case -1: e(30); default: /* Wait for the child to write something to the slave. */ FD_ZERO(&fd_set); FD_SET(masterfd, &fd_set); if (select(masterfd + 1, &fd_set, NULL, NULL, NULL) != 1) e(31); if (!FD_ISSET(masterfd, &fd_set)) e(32); if (read(masterfd, &c, sizeof(c)) != sizeof(c)) e(33); if (c != 'A') e(34); /* Write a reply once the child is blocked in its select. */ tv.tv_sec = 1; tv.tv_usec = 0; if (select(masterfd + 1, &fd_set, NULL, NULL, &tv) != 0) e(35); c = 'B'; if (write(masterfd, &c, sizeof(c)) != sizeof(c)) e(36); /* Wait for the child to request closing the master. */ if (read(masterfd, &c, sizeof(c)) != sizeof(c)) e(37); if (c != 'C') e(38); /* Close the master once the child is blocked in its select. */ sleep(1); close(masterfd); break; } if (waitchild() < 0) e(39); if (sigaction(SIGHUP, &oact, NULL) < 0) e(28); }
/* * Test receiving of SIGHUP on master hang-up. All of the tests so far have * ignored SIGHUP, and probably would not have received one anyway, since the * process was not its own session leader. Time to test this aspect. */ static void test77e(void) { struct sigaction act, hup_oact, usr_oact; sigset_t set, oset; char pname[PATH_MAX], tname[PATH_MAX]; int masterfd, slavefd; subtest = 5; /* Get master and slave device names for a free pseudo terminal. */ get_names(pname, tname); memset(&act, 0, sizeof(act)); act.sa_handler = signal_handler; if (sigaction(SIGHUP, &act, &hup_oact) < 0) e(1); memset(&act, 0, sizeof(act)); act.sa_handler = signal_handler; if (sigaction(SIGUSR1, &act, &usr_oact) < 0) e(2); sigemptyset(&set); sigaddset(&set, SIGHUP); sigaddset(&set, SIGUSR1); if (sigprocmask(SIG_BLOCK, &set, &oset) < 0) e(3); sighups = 0; /* Make ourselves process group leader if we aren't already. */ (void) setsid(); if ((masterfd = open(pname, O_RDWR | O_NOCTTY)) < 0) e(4); switch (fork()) { case 0: if (close(masterfd) < 0) e(5); /* Become session leader. */ if (setsid() < 0) e(6); if ((slavefd = open(tname, O_RDWR)) < 0) e(7); /* Tell the parent we are ready. */ kill(getppid(), SIGUSR1); /* We should now get a SIGHUP. */ set = oset; if (sigsuspend(&set) >= 0) e(8); if (sighups != 1) e(9); exit(errct); case -1: e(10); default: break; } /* Wait for SIGUSR1 from the child. */ set = oset; if (sigsuspend(&set) >= 0) e(11); /* Closing the master should now raise a SIGHUP signal in the child. */ if (close(masterfd) < 0) e(12); if (waitchild() < 0) e(13); if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0) e(14); if (sigaction(SIGHUP, &hup_oact, NULL) < 0) e(15); if (sigaction(SIGUSR1, &usr_oact, NULL) < 0) e(16); }
/* * Test opening the slave side with and without the O_NOCTTY flag. */ static void test77d(void) { char pname[PATH_MAX], tname[PATH_MAX]; int masterfd, slavefd; subtest = 4; /* Get master and slave device names for a free pseudo terminal. */ get_names(pname, tname); /* Make ourselves process group leader if we aren't already. */ (void) setsid(); if ((masterfd = open(pname, O_RDWR | O_NOCTTY)) < 0) e(1); /* * Opening the slave with O_NOCTTY should not change its controlling * terminal. */ switch (fork()) { case 0: if (setsid() < 0) e(2); if ((slavefd = open(tname, O_RDWR | O_NOCTTY)) < 0) e(3); if (open("/dev/tty", O_RDWR) >= 0) e(4); if (errno != ENXIO) e(5); exit(errct); case -1: e(6); default: break; } if (waitchild() < 0) e(7); if (close(masterfd) < 0) e(8); if ((masterfd = open(pname, O_RDWR | O_NOCTTY)) < 0) e(9); /* * Opening the slave without O_NOCTTY should change its controlling * terminal, though. */ switch (fork()) { case 0: if (setsid() < 0) e(10); if ((slavefd = open(tname, O_RDWR)) < 0) e(11); if (open("/dev/tty", O_RDWR) < 0) e(12); exit(errct); case -1: e(13); default: break; } if (waitchild() < 0) e(14); if (close(masterfd) < 0) e(15); }
/* * Test opening the slave side with and without the O_NOCTTY flag. */ static void test77d(void) { char pname[PATH_MAX], tname[PATH_MAX]; int masterfd, slavefd; subtest = 4; /* Make ourselves process group leader if we aren't already. */ (void)setsid(); /* Obtain a pseudo terminal. */ (void)get_pty(&masterfd, NULL, tname); /* * Opening the slave with O_NOCTTY should not change its controlling * terminal. */ switch (fork()) { case 0: if (close(masterfd) < 0) e(0); if (setsid() < 0) e(0); if ((slavefd = open(tname, O_RDWR | O_NOCTTY)) < 0) e(0); if (open("/dev/tty", O_RDWR) >= 0) e(0); if (errno != ENXIO) e(0); exit(errct); case -1: e(0); default: break; } if (waitchild() < 0) e(0); if (close(masterfd) < 0) e(0); (void)get_pty(&masterfd, pname, tname); /* * Opening the slave without O_NOCTTY should change its controlling * terminal, though. */ switch (fork()) { case 0: if (close(masterfd) < 0) e(0); if (setsid() < 0) e(0); if ((slavefd = open(tname, O_RDWR)) < 0) e(0); if (open("/dev/tty", O_RDWR) < 0) e(0); exit(errct); case -1: e(0); default: break; } if (waitchild() < 0) e(0); if (close(masterfd) < 0) e(0); }