struct ProcChild * proc_fork(void (*child_func)(void), const char *desc) { pid_t pid; int fdr[2], fdw[2]; pipe(fdr); pipe(fdw); pid = fork(); if (pid == -1) return NULL; if (pid == 0) { // new child process starts close(fdw[1]); close(fdr[0]); memset(&my_proc, 0, sizeof(struct Proc)); my_proc.parent.from = fdw[0]; my_proc.parent.to = fdr[1]; my_proc.parent.pid = getppid(); my_proc.desc = desc; handle_signals(); log_debug(LOG_PROC, "%s process %d started\n", desc, getpid()); child_func(); proc_finish(); while (1) {} // to keep gcc happy } else { // parent process continues close(fdw[0]); close(fdr[1]); return add_child(pid, fdw[1], fdr[0], desc); } }
static int test_child(int (*child_func) (void)) { struct stat st1, st2; int r; /* make sure we don't propagate mounts back to the parent */ r = mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL); assert(r >= 0); r = stat(b1_mountpath, &st1); assert(r >= 0); /* mount fresh domain */ r = mount(b1_filesystem, b1_mountpath, b1_filesystem, MS_NOSUID | MS_NOEXEC | MS_NODEV, NULL); assert(r >= 0); r = stat(b1_mountpath, &st2); assert(r >= 0); /* new domain must not equal parent domain */ assert(st1.st_dev != st2.st_dev); return child_func(); }
/* To open and start new * python shell process */ gboolean ptyFork (ChildProcessData *python_shell_data, GError **error) { int mfd, slaveFd, savedErrno; mfd = posix_openpt (O_RDWR | O_NOCTTY | O_NONBLOCK); grantpt (mfd); unlockpt (mfd); python_shell_data->master_fd = mfd; python_shell_data->slave_name = g_strdup (ptsname (mfd)); python_shell_data->sh_argv = g_malloc0 (sizeof (gchar *)); python_shell_data->sh_argv[0] = g_strdup ("/bin/sh"); /*if (!g_spawn_async (python_shell_data->current_dir, python_shell_data->argv, NULL, 0, child_func, (gpointer)python_shell_data, &(python_shell_data->pid), error)) return FALSE;*/ pid_t childPid = fork (); if (childPid == 0) { child_func ((gpointer)python_shell_data); execv (python_shell_data->sh_argv [0], python_shell_data->sh_argv); } python_shell_data->pid = childPid; return TRUE; }
void test_setup(int i, char *argv0) { char nobody_uid[] = "nobody"; struct passwd *ltpuser; switch (i) { case 0: break; case 1: header.version = _LINUX_CAPABILITY_VERSION; header.pid = 0; break; case 2: header.version = INVALID_VERSION; header.pid = 0; break; case 3: header.version = _LINUX_CAPABILITY_VERSION; /* * when a non-zero pid is specified, process should have * CAP_SETPCAP capability to change capabilities. * by default, CAP_SETPCAP is not enabled. So giving * a non-zero pid results in capset() failing with * errno EPERM * * Note: this seems to have changed with recent kernels * => create a child and try to set its capabilities */ child_pid = FORK_OR_VFORK(); if (child_pid == -1) tst_brkm(TBROK | TERRNO, cleanup, "fork failed"); else if (child_pid == 0) { #ifdef UCLINUX if (self_exec(argv0, "") < 0) { perror("self_exec failed"); exit(1); } #else child_func(); #endif } else { header.pid = child_pid; ltpuser = getpwnam(nobody_uid); if (ltpuser == NULL) tst_brkm(TBROK | TERRNO, cleanup, "getpwnam failed"); if (seteuid(ltpuser->pw_uid) == -1) tst_brkm(TBROK | TERRNO, cleanup, "seteuid failed"); } break; } }
/** The main function reads command line arguments, opens * the log and forks the child process. */ int main(int argc, char** argv) { int pid; char *infilename, *outfilename; FILE *infile, *outfile; sigset_t ss; infile = NULL; outfile = NULL; if (argc < 3 || argc > 4) { print_usage(); exit(-1); } infilename = argv[1]; outfilename = argv[2]; if (argc > 3) { if ((logfile = fopen(argv[3], "w")) == NULL) { perror("unable to open logfile"); print_usage(); exit(-1); } } else logfile = stdout; fprintf(logfile, "%ld: log opened\n", (long int)time(NULL)); /** Create a blocking sigprocmask for the morse code signals so * that the blocked signals can be caught with sigtimedwait * instead of the signal handler * */ sigemptyset(&ss); sigaddset(&ss, MORSE_SHORT); sigaddset(&ss, MORSE_LONG); sigaddset(&ss, MORSE_PAUSE); sigprocmask(SIG_BLOCK, &ss, NULL); /* Fork the child process */ if ((pid = fork()) < 0){ perror("fork error"); exit(-1); } if (pid == 0) { /* In child */ child_func(infilename,infile); fflush(logfile); fclose(logfile); } else { /* In parent */ parent_func(outfilename, outfile, pid); fflush(logfile); fclose(logfile); } return 0; }
struct ProcChild * proc_fork(void (*child_func)(void), const char *desc) { pid_t pid; int fdr[2], fdw[2]; int i; pipe(fdr); pipe(fdw); pid = fork(); if (pid == -1) return NULL; if (pid == 0) { // new child process starts // we have to close unneeded pipes inherited from the parent if (my_proc.parent.to != -1) close(my_proc.parent.to); if (my_proc.parent.from != -1) close(my_proc.parent.from); for (i = 0; i < my_proc.nr_children; i++) { close(my_proc.children[i].to); close(my_proc.children[i].from); } close(fdw[1]); close(fdr[0]); // stop parent's pipes from propagating through an exec() fcntl(fdw[0], F_SETFD, FD_CLOEXEC); fcntl(fdr[1], F_SETFD, FD_CLOEXEC); // now setup our own data memset(&my_proc, 0, sizeof(struct Proc)); my_proc.parent.from = fdw[0]; my_proc.parent.to = fdr[1]; my_proc.parent.pid = getppid(); my_proc.desc = desc; handle_signals(); set_my_name(desc); log_debug(LOG_PROC, "%s process %d started\n", desc, getpid()); // finally jump to the real function child_func(); proc_finish(); while (1) {} // to keep gcc happy } else { // parent process continues close(fdw[0]); close(fdr[1]); return add_child(pid, fdw[1], fdr[0], desc); } }
static void test(void) { pid_t pid; int status; /* unshares the network namespace */ if (unshare(CLONE_NEWNET) == -1) tst_brkm(TBROK | TERRNO, cleanup, "unshare failed"); pid = tst_fork(); if (pid < 0) { tst_brkm(TBROK | TERRNO, cleanup, "fork failed"); } if (pid == 0) { _exit(child_func()); } /* creates TAP network interface dummy0 */ if (WEXITSTATUS(system("ip tuntap add dev dummy0 mode tap")) == -1) tst_brkm(TBROK | TERRNO, cleanup, "system failed"); /* removes previously created dummy0 device */ if (WEXITSTATUS(system("ip tuntap del mode tap dummy0")) == -1) tst_brkm(TBROK | TERRNO, cleanup, "system failed"); /* allow child to continue */ TST_SAFE_CHECKPOINT_WAKE(cleanup, 0); SAFE_WAITPID(cleanup, pid, &status, 0); if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { tst_resm(TFAIL, "netlink interface fail"); return; } if (WIFSIGNALED(status)) { tst_resm(TFAIL, "child was killed with signal %s", tst_strsig(WTERMSIG(status))); return; } tst_resm(TPASS, "netlink interface pass"); }
int main(int argc, char *argv[]) { int nchildren = 1; int pid; int x; if (argc > 1) { nchildren = atoi(argv[1]); } for (x = 0; x < nchildren; x++) { if ((pid = fork()) == 0) { child_func(x + 1); exit(0); } } wait(NULL); return 0; }
static int fork_and_wait_child (void (*child_func) (void)) { pid_t pid; int status; pid = fork (); ATF_REQUIRE (pid != -1); if (pid == 0) { status = 0; /* Silence compiler warnings */ child_func (); UNREACHABLE; } else { ATF_REQUIRE (waitpid (pid, &status, 0) != 0); } return status; }
static int create_child_and_init_lib(int n, Prolib_t *lib, void(*child_func)(int numth, Prolib_t *lib)) { int i; pid_t pid; for (i = 0; i < n; i++) { pid = fork(); if (-1 == pid ) { perror("fork"); return -1; } if (0 == pid) { lib[i].pid = getpid(); child_func(i, lib); exit(0); } } return 0; }
void parent_func() { int parent_var; child_func(&parent_var); }
int child_func(void) { int i, fd; struct timespec ts = {.tv_sec = 0, .tv_nsec = 0}; int msec = 0; sleep(1); srand(time(NULL)); for (i=0; i<NLOOP; i++) { sprintf(name, SHM_NAME, i); fd = shm_open(name, O_RDONLY|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR); if (fd != -1) { sem_wait(sem); //fprintf(stderr, "%d: %d\n", getpid(), *create_cnt); (*create_cnt)++; sem_post(sem); } /* get a random number [0, 20] */ msec = (int) (20.0 * rand() / RAND_MAX) ; ts.tv_nsec = msec * 1000000; nanosleep(&ts, NULL); } return 0; } int main() { int i, pid, result_fd; char semname[20]; snprintf(semname, 20, "/sem23-1_%d", getpid()); sem = sem_open(semname, O_CREAT, 0777, 1); if (sem == SEM_FAILED || sem == NULL) { perror("error at sem_open"); return PTS_UNRESOLVED; } sem_unlink(semname); result_fd = shm_open(SHM_RESULT_NAME, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); if (result_fd == -1) { perror("An error occurs when calling shm_open()"); return PTS_UNRESOLVED; } shm_unlink(SHM_RESULT_NAME); if (ftruncate(result_fd, sizeof(*create_cnt)) != 0) { perror("An error occurs when calling ftruncate()"); shm_unlink(SHM_RESULT_NAME); return PTS_UNRESOLVED; } create_cnt = mmap(NULL, sizeof(*create_cnt), PROT_WRITE, MAP_SHARED, result_fd, 0); if (create_cnt == MAP_FAILED) { perror("An error occurs when calling mmap()"); shm_unlink(SHM_RESULT_NAME); return PTS_UNRESOLVED; } *create_cnt = 0; for (i=0; i<NPROCESS; i++) { pid = fork(); if (pid == -1) { perror("An error occurs when calling fork()"); return PTS_UNRESOLVED; } else if (pid == 0) { child_func(); exit(0); } } while (wait(NULL) > 0); for (i=0; i<NLOOP; i++) { sprintf(name, SHM_NAME, i); shm_unlink(name); } fprintf(stderr, "create_cnt: %d\n", *create_cnt); if (*create_cnt != NLOOP) { printf("Test FAILED\n"); return PTS_FAIL; } return PTS_PASS; }
static int test_sig(void (*child_func)(void), int expected_sig, int expected_code) { int code, term_sig; int child_pid; int wstatus; int rc; child_pid = fork(); if (child_pid < 0) { printf("fork() failed\n"); return 1; } if (!child_pid) { child_func(); exit(0); } rc = waitpid(-1, &wstatus, 0); if (rc != child_pid) { printf("waitpid returned %d instead of child's pid: %d\n", rc, child_pid); return 1; } code = WEXITSTATUS(wstatus); term_sig = WTERMSIG(wstatus); if (expected_sig > 0) { if (code != 0) { printf("ERROR: expected child to exit with 0, got: %d\n", code); return 1; } if (term_sig != expected_sig) { printf("ERROR: expected child exit due to signal " "%d, instead got terminated by: %d\n", expected_sig, term_sig); return 1; } printf("The child exited with signal %d, as expected.\n", expected_sig); } else { if (term_sig != 0) { printf("ERROR: expected child to exit with code %d, " "it got terminated with signal: %d\n", expected_code, term_sig); return 1; } if (code != expected_code) { printf("ERROR: expected child exit with " "code %d, got: %d\n", expected_code, code); return 1; } printf("The child exited with code %d, as expected.\n", expected_code); } return 0; }
int main(int argc, char *argv[]) { sem_t *sem_mutex; //Binary semaphore to use a mutex int *stateptr; //Shared memory global int to store active button state int hit_count = 0, rows, cols; WINDOW *mainwin = NULL; int nextch; MEVENT event; struct sigaction act; //Create a binary semaphore to use as a mutex: //(will be inerited by children) if ((sem_mutex = sem_open("/mutex", O_CREAT|O_EXCL, 0600, 1)) == SEM_FAILED) { perror("Semaphore creation failed"); return EXIT_FAILURE; } //Now unlink semaphore so it will be deleted in case of ^-C or crash: sem_unlink("/mutex"); //Setup anonymous, shared memory for global int: if ((stateptr = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) { perror("Shared memory creation failed"); return EXIT_FAILURE; } //Initialize button state (no active buttons): *stateptr = 0; //Initialize and setup the curses window: if ((mainwin = initscr()) == NULL) { fprintf(stderr,"Failed to initialize curses window\n"); return EXIT_FAILURE; } getmaxyx(mainwin,rows,cols); mvprintw(rows/2,cols/2-18,"Click on the Corner Buttons to Score!",rows,cols); mvprintw(rows/2+2,cols/2-10,"(rows: %d cols: %d)",rows,cols); refresh(); //Setup signal handler for SIGCHLD signals: memset(&act,0,sizeof(act)); act.sa_handler = sigchld_handler; sigemptyset(&act.sa_mask); sigaction(SIGCHLD,&act,NULL); //Create children: //**************** for (int i=0; i < running; i++){//memory problem??? switch(fork()){ case -1: perror("fork failed"); sigchld_handler(EXIT_FAILURE); endwin();//put this in here since failures don't close the window apparently. exit(EXIT_FAILURE); case 0: child_func(1+i, rows, cols,sem_mutex,stateptr);//1+processcount allows for proper numbering. sigchld_handler(EXIT_SUCCESS); exit(EXIT_SUCCESS); default: break;//no break leads to error apparently. //I got it now the switch statement will determine the parent function follows the default. } } //Setup curses to get mouse events: keypad(mainwin, TRUE); mousemask(ALL_MOUSE_EVENTS, NULL); //Loop catching mouse clicks while children are running: while (running > 0) { //nextch = wgetch(mainwin); if ((nextch = getch()) == KEY_MOUSE && getmouse(&event) == OK && (event.bstate & BUTTON1_PRESSED)) { //Check if user clicked on a label: if (check_click(*stateptr, event.x, event.y, rows, cols)) { //Clicked on current label: hit_count++; mvprintw(rows/2+5,cols/2-11,"Got #%d at (%3d,%3d)",*stateptr,event.x,event.y); wrefresh(curscr); //Need this to ensure entire screen is redrawn despite child changes. } } } //Close curses window so terminal settings are restored to normal: endwin(); //Print out results: printf("\nYour hit count was: %d\n\n",hit_count); //Collect all the children: //************************* //return exit success if child successfully exited. int status; int tempcount = 0;//made a temp count since I think running will be 0 by now. while(tempcount<4){ wait(&status);// wait for children shouldn't all return status if(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS){ tempcount++;//increment temp count. }else exit(EXIT_FAILURE);//return exit failure according to lecture. } exit(EXIT_SUCCESS);//completes while loop so returns exit success. }