int main() { while (TRUE) { // print prompt and read into string array input. print_prompt(); char* input[64]; scan_input(input); // perform a fork and process input. int pid = fork(); if (pid != 0) { // code for parent process. int statloc; process_parent(&statloc); } else { // code for forked child process. process_child(input); } } }
int main( int argc, char *argv[] ) { int skipcount=parse_cmdline( argc, argv ); int ret=0; /* Warn if we're run as SUID */ if( getuid()!=geteuid() ) { fprintf(stderr, "!!!!Running privbind SUID is a security risk!!!!\n"); } /* Create a couple of sockets for communication with our children */ int sv[2]; if( socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sv)<0 ) { perror("privbind: socketpair"); return 2; } pid_t child_pid=fork(); /* http://sourceforge.net/mailarchive/message.php?msg_name=20070601194744.GA29875%40fermat.math.technion.ac.il * Reverse the usual role of "parent" and "child". * Parent process perform "child" actions - running the command. * Child process is the one that listens on the socket and handles the binds */ switch(child_pid) { case -1: perror("privbind: fork"); exit(1); case 0: /* We are the child */ ret=process_parent( sv ); break; default: /* We are the parent */ { /* Wait for the child to exit. */ int status=0; do { waitpid( child_pid, &status, 0 ); } while( !WIFEXITED(status) && !WIFSIGNALED(status) ); if( WIFEXITED(status) ) { ret=WEXITSTATUS(status); if( ret==0 ) { /* Child has indicated that it is ready */ ret=process_child( sv, argc-skipcount, argv+skipcount ); } } else { fprintf(stderr, "privbind: root process terminated with signal %d\n", WTERMSIG(status) ); ret=2; } } break; } return ret; }
int main(int argc, char *argv[]) { int i, n_count, sem_value, status; if (argc != 2) { printf("%s [counter]\n", argv[0]); exit(EXIT_FAILURE); } n_count = atoi(argv[1]); p_psem = sem_open(NAME_POSIX_SEM, O_CREAT | O_EXCL, 0600, n_count); if (p_psem == SEM_FAILED) { if (errno != EEXIST) { perror("FAIL: sem_open"); exit(EXIT_FAILURE); } p_psem = sem_open(NAME_POSIX_SEM, 0); printf("[%d] Attach to an existed sem \n", getpid()); } else printf("[%d] Create new sem \n", getpid()); sem_getvalue(p_psem, &sem_value); printf("[%d] sem_getvalue = %d\n", getpid(), sem_value); for (i = 0; i < max_child; i++) { printf("[%d] iteration(%d) : Atomically decrease\n", getpid(), i); sem_wait(p_psem); switch ( fork() ) { case 0: /* child */ process_child(i); sem_post(p_psem); exit(EXIT_SUCCESS); case -1: /* error */ fprintf(stderr, "FAIL: fork() [%s:%d]\n", __FUNCTION__, __LINE__); exit(EXIT_FAILURE); default: /* parrent */ break; } usleep(10000); } for (i = 0; i < max_child; i++) { pid_t pid_child; if ((pid_child = waitpid(-1, &status, 0)) == -1) { perror("waitpid error"); continue; } } sem_getvalue(p_psem, &sem_value); printf("[%d] sem_getvalue = %d \n", getpid(), sem_value); if (sem_unlink(NAME_POSIX_SEM) == -1) { perror("sem_unlink error"); exit(EXIT_FAILURE); } return EXIT_SUCCESS; }
int main() { while (TRUE) { // print prompt and read into string array input. print_prompt(); char* input[64]; scan_input(input); int input_len = array_len(input); int option = 0; // if last parameter is an & then run child process in background. /*if (input_len != 0 && !strcmp(input[input_len], "&")) { option = 1; input[input_len] = NULL; }*/ /* pass to change_directory if input is a cd command. Else perform a fork and process input. */ if (input_len != 0 && !strcmp(input[0], "cd")) { change_directory(input); } else if (input_len != 0 && fork() != 0) { // code for parent process. int statloc; process_parent(&statloc, option); } else if (input_len != 0) { // code for forked child process. process_child(input); } } }
int do_process(void) { struct kevent ke; int kq, status; pid_t pid, pid2; int didfork, didchild; int i; struct timespec ts; /* * Timeout in case something doesn't work. */ ts.tv_sec = 10; ts.tv_nsec = 0; ASS((kq = kqueue()) >= 0, warn("kqueue")); /* * Install a signal handler so that we can use pause() to synchronize * with the child with the parent. */ signal(SIGUSR1, usr1handler); switch ((pid = fork())) { case -1: err(1, "fork"); case 0: _exit(process_child()); } sleep(2); /* wait for child to settle down. */ EV_SET(&ke, pid, EVFILT_PROC, EV_ADD|EV_ENABLE|EV_CLEAR, NOTE_EXIT|NOTE_FORK|NOTE_EXEC|NOTE_TRACK, 0, NULL); ASS(kevent(kq, &ke, 1, NULL, 0, NULL) == 0, warn("can't register events on kqueue")); kill(pid, SIGUSR1); /* sync 1 */ didfork = didchild = 0; pid2 = -1; for (i = 0; i < 2; i++) { ASS(kevent(kq, NULL, 0, &ke, 1, &ts) == 1, warnx("didn't receive event")); ASSX(ke.filter == EVFILT_PROC); switch (ke.fflags) { case NOTE_CHILD: didchild = 1; ASSX((pid_t)ke.data == pid); pid2 = ke.ident; fprintf(stderr, "child %d\n", pid2); break; case NOTE_FORK: didfork = 1; ASSX(ke.ident == pid); fprintf(stderr, "fork\n"); break; case NOTE_TRACKERR: errx(1, "child tracking failed due to resource shortage"); default: errx(1, "kevent returned weird event 0x%x pid %d", ke.fflags, (pid_t)ke.ident); } } if (pid2 == -1) return (1); /* Both children now sleeping. */ ASSX(didchild == didfork == 1); kill(pid2, SIGUSR1); /* sync 2.1 */ kill(pid, SIGUSR1); /* sync 2 */ if (wait(&status) < 0) err(1, "wait"); if (!WIFEXITED(status)) errx(1, "child didn't exit?"); close(kq); return (WEXITSTATUS(status) != 0); }