int start2(char *arg) { int kid_pid; USLOSS_Console("start2(): started. Creating mailbox.\n"); mailbox = MboxCreate(0, 0); if (mailbox == -1) { USLOSS_Console("start2(): got non-zero mailbox result. Quitting...\n"); quit(1); } USLOSS_Console("\nstart2(): calling fork1 for Child1a\n"); fork1("Child1a", Child1, "Child1a", USLOSS_MIN_STACK, 1); USLOSS_Console("start2(): calling fork1 for Child1b\n"); fork1("Child1b", Child1, "Child1b", USLOSS_MIN_STACK, 1); USLOSS_Console("start2(): calling fork1 for Child1c\n"); fork1("Child1c", Child1, "Child1c", USLOSS_MIN_STACK, 1); USLOSS_Console("start2(): calling fork1 for Child2\n"); fork1("Child2", Child2, NULL, USLOSS_MIN_STACK, 2); USLOSS_Console("\nstart2(): Parent done forking.\n"); int status; kid_pid = join(&status); USLOSS_Console("Process %d joined with status: %d\n\n", kid_pid, status); kid_pid = join(&status); USLOSS_Console("Process %d joined with status: %d\n\n", kid_pid, status); kid_pid = join(&status); USLOSS_Console("Process %d joined with status: %d\n\n", kid_pid, status); kid_pid = join(&status); USLOSS_Console("Process %d joined with status: %d\n\n", kid_pid, status); quit(8); return 0; } /* start2 */
int start1(char *arg) { int pid1; printf("start1(): started\n"); pid1 = fork1("XXp1", XXp1, "XXp1", USLOSS_MIN_STACK, 9); if(pid1 == -1) printf("start1(): couldn't fork a child -- invalid priority\n"); pid1 = fork1("XXp1", XXp1, "XXp1", USLOSS_MIN_STACK, -10); if(pid1 == -1) printf("start1(): couldn't fork a child -- invalid priority\n"); return 0; /* so gcc will not complain about its absence... */ }
/* * vfork * * Description: vfork system call * * Parameters: void [no arguments] * * Retval: 0 (to child process) * !0 pid of child (to parent process) * -1 error (see "Returns:") * * Returns: EAGAIN Administrative limit reached * EINVAL vfork() called during vfork() * ENOMEM Failed to allocate new process * * Note: After a successful call to this function, the parent process * has its task, thread, and uthread lent to the child process, * and control is returned to the caller; if this function is * invoked as a system call, the return is to user space, and * is effectively running on the child process. * * Subsequent calls that operate on process state are permitted, * though discouraged, and will operate on the child process; any * operations on the task, thread, or uthread will result in * changes in the parent state, and, if inheritable, the child * state, when a task, thread, and uthread are realized for the * child process at execve() time, will also be effected. Given * this, it's recemmended that people use the posix_spawn() call * instead. * * BLOCK DIAGRAM OF VFORK * * Before: * * ,----------------. ,-------------. * | | task | | * | parent_thread | ------> | parent_task | * | | <.list. | | * `----------------' `-------------' * uthread | ^ bsd_info | ^ * v | vc_thread v | task * ,----------------. ,-------------. * | | | | * | parent_uthread | <.list. | parent_proc | <-- current_proc() * | | | | * `----------------' `-------------' * uu_proc | * v * NULL * * After: * * ,----------------. ,-------------. * | | task | | * ,----> | parent_thread | ------> | parent_task | * | | | <.list. | | * | `----------------' `-------------' * | uthread | ^ bsd_info | ^ * | v | vc_thread v | task * | ,----------------. ,-------------. * | | | | | * | | parent_uthread | <.list. | parent_proc | * | | | | | * | `----------------' `-------------' * | uu_proc | . list * | v v * | ,----------------. * `----- | | * p_vforkact | child_proc | <-- current_proc() * | | * `----------------' */ int vfork(proc_t parent_proc, __unused struct vfork_args *uap, int32_t *retval) { thread_t child_thread; int err; if ((err = fork1(parent_proc, &child_thread, PROC_CREATE_VFORK, NULL)) != 0) { retval[1] = 0; } else { uthread_t ut = get_bsdthread_info(current_thread()); proc_t child_proc = ut->uu_proc; retval[0] = child_proc->p_pid; retval[1] = 1; /* flag child return for user space */ /* * Drop the signal lock on the child which was taken on our * behalf by forkproc()/cloneproc() to prevent signals being * received by the child in a partially constructed state. */ proc_signalend(child_proc, 0); proc_transend(child_proc, 0); proc_knote(parent_proc, NOTE_FORK | child_proc->p_pid); DTRACE_PROC1(create, proc_t, child_proc); ut->uu_flag &= ~UT_VFORKING; } return (err); }
int main(int argc, char* argv[]) { static char buf[BUFSIZ]; int fd; whitespace = " \t\r\n\v"; symbols = "<|>&;()"; if (argc == 2 && !strcmp(argv[1], "-i")) interactive = 1; // Assumes three file descriptors open. while ((fd = open("/dev/console", O_RDWR)) >= 0) { if (fd >= 3) { close(fd); break; } } // Read and run input commands. while (getcmd(buf) >= 0) { if (!memcmp(buf, "cd ", 3)) { // Clumsy but will have to do for now. // Chdir has no effect on the parent if run in the child. if (chdir(buf + 3) < 0) dprintf(2, "cannot cd %s\n", buf + 3); continue; } else if (!strcmp(buf, "exit")) return 0; // XXX should allow return code (exit [n]) if (fork1() == 0) runcmd(parsecmd(buf)); wait(); } return 0; }
int linux_fork(struct thread *td, struct linux_fork_args *args) { struct fork_req fr; int error; struct proc *p2; struct thread *td2; #ifdef DEBUG if (ldebug(fork)) printf(ARGS(fork, "")); #endif bzero(&fr, sizeof(fr)); fr.fr_flags = RFFDG | RFPROC | RFSTOPPED; fr.fr_procp = &p2; if ((error = fork1(td, &fr)) != 0) return (error); td2 = FIRST_THREAD_IN_PROC(p2); linux_proc_init(td, td2, 0); td->td_retval[0] = p2->p_pid; /* * Make this runnable after we are finished with it. */ thread_lock(td2); TD_SET_CAN_RUN(td2); sched_add(td2, SRQ_BORING); thread_unlock(td2); return (0); }
/* * Create a kernel process/thread/whatever. It shares it's address space * with proc0 - ie: kernel only. */ int kthread_create2(void (*func)(void *), void *arg, struct proc **newpp, int flags, const char *fmt, ...) { int error; va_list ap; struct proc *p2; if (!proc0.p_stats || proc0.p_stats->p_start.tv_sec == 0) { panic("kthread_create called too soon"); } error = fork1(&proc0, RFMEM | RFFDG | RFPROC | flags, &p2); if (error) return error; /* save a global descriptor, if desired */ if (newpp != NULL) *newpp = p2; /* this is a non-swapped system process */ p2->p_flag |= P_INMEM | P_SYSTEM; p2->p_procsig->ps_flag |= PS_NOCLDWAIT; PHOLD(p2); /* set up arg0 for 'ps', et al */ va_start(ap, fmt); vsnprintf(p2->p_comm, sizeof(p2->p_comm), fmt, ap); va_end(ap); /* call the processes' main()... */ cpu_set_fork_handler(p2, func, arg); return 0; }
/* * rfork() */ int freebsd_sys_rfork(struct lwp *l, void *v, register_t *retval) { struct freebsd_sys_rfork_args /* { syscallargs(int) flags; } */ *uap = v; int flags; flags = 0; if ((SCARG(uap, flags) & (FREEBSD_RFFDG | FREEBSD_RFCFDG)) == (FREEBSD_RFFDG | FREEBSD_RFCFDG)) return (EINVAL); if ((SCARG(uap, flags) & FREEBSD_RFPROC) == 0) return (EINVAL); if (SCARG(uap, flags) & FREEBSD_RFNOWAIT) flags |= FORK_NOWAIT; if (SCARG(uap, flags) & FREEBSD_RFMEM) flags |= FORK_SHAREVM; if (SCARG(uap, flags) & FREEBSD_RFSIGSHARE) flags |= FORK_SHARESIGS; if (SCARG(uap, flags) & FREEBSD_RFCFDG) flags |= FORK_CLEANFILES; else if ((SCARG(uap, flags) & FREEBSD_RFFDG) == 0) flags |= FORK_SHAREFILES; return (fork1(l, flags, SCARG(uap, flags) & FREEBSD_RFLINUXTHPN ? SIGUSR1 : SIGCHLD, NULL, 0, NULL, NULL, retval, NULL)); }
int main(void) { static char buf[100]; int fd; // Assumes three file descriptors open. while((fd = open("console", O_RDWR)) >= 0) { if(fd >= 3){ close(fd); break; } } // Read and run input commands. while(getcmd(buf, sizeof(buf)) >= 0) { if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){ // Clumsy but will have to do for now. // Chdir has no effect on the parent if run in the child. buf[strlen(buf)-1] = 0; // chop \n if(chdir(buf+3) < 0) printf(2, "cannot cd %s\n", buf+3); continue; } else if(buf[0] == 'v' && buf[1] == 'e' && buf[2] == 'r' && buf[3] == 's' && buf[4] == 'i' && buf[5] == 'o' && buf[6] == 'n') printf(1, "uNIX Version 0-1 \n Build Version 3"); if(fork1() == 0) runcmd(parsecmd(buf)); wait(); } exit(); }
int main(void) { static char buf[100]; int fd, r; // Read and run input commands. while(getcmd(buf, sizeof(buf)) >= 0){ if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){ // Clumsy but will have to do for now. // Chdir has no effect on the parent if run in the child. buf[strlen(buf)-1] = 0; // chop \n if(chdir(buf+3) < 0) fprintf(stderr, "cannot cd %s\n", buf+3); continue; } /* also clumsy: can't use exit* programs, but ok since not traversing PATH anyway.*/ if(!strncmp(buf, "exit", 4)) { exit(0); } if(fork1() == 0) runcmd(parsecmd(buf)); wait(&r); } exit(0); }
int main(void) { static char buf[100]; int fd, status; // Assumes three file descriptors open. while((fd = open("console", O_RDWR)) >= 0){ if(fd >= 3){ close(fd); break; } } // Read and run input commands. while(getcmd(buf, sizeof(buf)) >= 0){ if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){ // Clumsy but will have to do for now. // Chdir has no effect on the parent if run in the child. buf[strlen(buf)-1] = 0; // chop \n if(chdir(buf+3) < 0) printf(2, "cannot cd %s\n", buf+3); continue; } if(fork1() == 0) runcmd(parsecmd(buf)); wait(&status); } exit(0); }
int main(void) { static char buf[100]; int fd, r; // Read and run input commands. while(getcmd(buf, sizeof(buf)) >= 0){ if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){ // Clumsy but will have to do for now. // Chdir has no effect on the parent if run in the child. buf[strlen(buf)-1] = 0; // chop \n if(chdir(buf+3) < 0) fprintf(stderr, "cannot cd %s\n", buf+3); continue; } if(strncmp(buf, "exit", 4) == 0) { fprintf(stdout, "Exit, good bye.\n"); exit(0); } if(fork1() == 0) runcmd(parsecmd(buf)); wait(&r); } exit(0); }
static int has_fs(char *prog, char *slice) { pid_t pid; int loc; mode_t mode = S_IRUSR | S_IWUSR; switch ((pid = fork1())) { case 0: /* child process */ closefrom(1); (void) open("/dev/null", O_WRONLY, mode); (void) open("/dev/null", O_WRONLY, mode); (void) execl(prog, "fstyp", slice, NULL); _exit(1); break; case -1: return (0); default: /* parent process */ break; } (void) waitpid(pid, &loc, 0); if (WIFEXITED(loc) && WEXITSTATUS(loc) == 0) { return (1); } return (0); }
/* * New vfork(2) system call for NetBSD, which implements original 3BSD vfork(2) * semantics. Address space is shared, and parent is blocked until child exit. */ int sys___vfork14(struct lwp *l, const void *v, register_t *retval) { return fork1(l, FORK_PPWAIT|FORK_SHAREVM, SIGCHLD, NULL, 0, NULL, NULL, retval, NULL); }
/* * vfork * * Description: vfork system call * * Parameters: void [no arguments] * * Retval: 0 (to child process) * !0 pid of child (to parent process) * -1 error (see "Returns:") * * Returns: EAGAIN Administrative limit reached * EINVAL vfork() called during vfork() * ENOMEM Failed to allocate new process * * Note: After a successful call to this function, the parent process * has its task, thread, and uthread lent to the child process, * and control is returned to the caller; if this function is * invoked as a system call, the return is to user space, and * is effectively running on the child process. * * Subsequent calls that operate on process state are permitted, * though discouraged, and will operate on the child process; any * operations on the task, thread, or uthread will result in * changes in the parent state, and, if inheritable, the child * state, when a task, thread, and uthread are realized for the * child process at execve() time, will also be effected. Given * this, it's recemmended that people use the posix_spawn() call * instead. * * BLOCK DIAGRAM OF VFORK * * Before: * * ,----------------. ,-------------. * | | task | | * | parent_thread | ------> | parent_task | * | | <.list. | | * `----------------' `-------------' * uthread | ^ bsd_info | ^ * v | vc_thread v | task * ,----------------. ,-------------. * | | | | * | parent_uthread | <.list. | parent_proc | <-- current_proc() * | | | | * `----------------' `-------------' * uu_proc | * v * NULL * * After: * * ,----------------. ,-------------. * | | task | | * ,----> | parent_thread | ------> | parent_task | * | | | <.list. | | * | `----------------' `-------------' * | uthread | ^ bsd_info | ^ * | v | vc_thread v | task * | ,----------------. ,-------------. * | | | | | * | | parent_uthread | <.list. | parent_proc | * | | | | | * | `----------------' `-------------' * | uu_proc | . list * | v v * | ,----------------. * `----- | | * p_vforkact | child_proc | <-- current_proc() * | | * `----------------' */ int vfork(proc_t parent_proc, __unused struct vfork_args *uap, int32_t *retval) { thread_t child_thread; int err; if ((err = fork1(parent_proc, &child_thread, PROC_CREATE_VFORK)) != 0) { retval[1] = 0; } else { /* * kludge: rely on uu_proc being set in the vfork case, * rather than returning the actual thread. We can remove * this when we remove the uu_proc/current_proc() kludge. */ proc_t child_proc = current_proc(); retval[0] = child_proc->p_pid; retval[1] = 1; /* flag child return for user space */ /* * Drop the signal lock on the child which was taken on our * behalf by forkproc()/cloneproc() to prevent signals being * received by the child in a partially constructed state. */ proc_signalend(child_proc, 0); proc_transend(child_proc, 0); /* flag the fork has occurred */ proc_knote(parent_proc, NOTE_FORK | child_proc->p_pid); DTRACE_PROC1(create, proc_t, child_proc); } return(err); }
int linux_fork(struct thread *td, struct linux_fork_args *args) { int error; struct proc *p2; struct thread *td2; #ifdef DEBUG if (ldebug(fork)) printf(ARGS(fork, "")); #endif if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2, NULL, 0)) != 0) return (error); td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; error = linux_proc_init(td, td->td_retval[0], 0); if (error) return (error); td2 = FIRST_THREAD_IN_PROC(p2); /* * Make this runnable after we are finished with it. */ thread_lock(td2); TD_SET_CAN_RUN(td2); sched_add(td2, SRQ_BORING); thread_unlock(td2); return (0); }
static int daemonize_self(void) { pid_t pid; int fd; (void) close(STDIN_FILENO); if ((fd = open(DEV_NULL, O_RDONLY)) == -1) { (void) printf("Could not open /dev/null: %s\n", strerror(errno)); } else if (fd != STDIN_FILENO) { (void) dup2(fd, STDIN_FILENO); (void) close(fd); } (void) dup2(STDERR_FILENO, STDOUT_FILENO); closefrom(3); if ((pid = fork1()) < 0) { (void) printf("fork() failed: %s\n", strerror(errno)); return (1); } if (pid != 0) exit(0); (void) setsid(); (void) chdir("/"); return (0); }
static FILE * open_conf_pipe(const char *cmd, char *argv[], pid_t *pidp) { int pfds[2]; pid_t pid; struct sigaction act; /* Create a pipe and fork a child process to run the command */ if (pipe(pfds) == -1) { logerror("failed to create pipe"); return (NULL); } if ((pid = fork1()) == -1) { logerror("failed to fork1"); goto err; } /* If we're in the child, run the command and output to the pipe */ if (pid == 0) { /* * We must set up to ignore these signals, which may be * propogated from the calling process. */ act.sa_handler = SIG_IGN; (void) sigaction(SIGHUP, &act, NULL); (void) sigaction(SIGALRM, &act, NULL); (void) sigaction(SIGUSR1, &act, NULL); (void) close(pfds[0]); (void) close(STDOUT_FILENO); if (dup2(pfds[1], STDOUT_FILENO) == -1) { logerror("failed to dup to stdout"); (void) close(pfds[1]); _exit(127); } (void) execvp(cmd, argv); logerror("failed to parse configuration file"); _exit(127); /*NOTREACHED*/ } /* If we're in the parent, open the read end of the pipe and return */ *pidp = pid; (void) close(pfds[1]); return (fdopen(pfds[0], "r")); err: (void) close(pfds[0]); (void) close(pfds[1]); return (NULL); }
int start2(char *arg) { int kid_status, kidpid, pausepid; int result; char buffer[]="hello"; USLOSS_Console("start2(): started\n"); mbox_id = MboxCreate(0, 50); USLOSS_Console("\nstart2(): MboxCreate returned id = %d\n", mbox_id); kidpid = fork1("XXp2a", XXp2, "XXp2a", 2 * USLOSS_MIN_STACK, 3); kidpid = fork1("XXp2b", XXp2, "XXp2b", 2 * USLOSS_MIN_STACK, 3); kidpid = fork1("XXp2c", XXp2, "XXp2c", 2 * USLOSS_MIN_STACK, 3); pausepid = fork1("XXp4", XXp4, "XXp4", 2 * USLOSS_MIN_STACK, 3); kidpid = join(&kid_status); if (kidpid != pausepid) USLOSS_Console("\n***Test Failed*** -- join with pausepid failed!\n\n"); kidpid = fork1("XXp3", XXp3, NULL, 2 * USLOSS_MIN_STACK, 2); kidpid = join(&kid_status); USLOSS_Console("\nstart2(): joined with kid %d, status = %d\n", kidpid, kid_status); kidpid = join(&kid_status); USLOSS_Console("\nstart2(): joined with kid %d, status = %d\n", kidpid, kid_status); kidpid = join(&kid_status); USLOSS_Console("\nstart2(): joined with kid %d, status = %d\n", kidpid, kid_status); kidpid = join(&kid_status); USLOSS_Console("\nstart2(): joined with kid %d, status = %d\n", kidpid, kid_status); result = MboxCondSend(mbox_id, buffer, strlen(buffer)+1); if(result == -1) USLOSS_Console("failed to send to released mailbox ... success\n"); else USLOSS_Console("test failed result = %d\n",result); quit(0); return 0; /* so gcc will not complain about its absence... */ } /* start2 */
int start1(char *arg) { int ret1,ret2,ret3; int status; pidlist[0] = fork1("XXp1", XXp1, NULL, USLOSS_MIN_STACK, 2); pidlist[1] = fork1("XXp1", XXp1, NULL, USLOSS_MIN_STACK, 3); pidlist[2] = fork1("XXp1", XXp1, NULL, USLOSS_MIN_STACK, 4); ret1=join(&status); ret2=join(&status); ret3=join(&status); USLOSS_Console("TEST:"); USLOSS_Console("exit getpid test.\n"); quit(-1); return 0; }
int main(void) { static char buf[100]; static char bufCNM[100]; int fd; // Assumes three file descriptors open. while((fd = open("console", O_RDWR)) >= 0){ if(fd >= 3){ close(fd); break; } } // Read and run input commands. while(getcmd(buf, sizeof(buf)) >= 0){ if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){ // Clumsy but will have to do for now. // Chdir has no effect on the parent if run in the child. buf[strlen(buf)-1] = 0; // chop \n if(chdir(buf+3) < 0) printf(2, "cannot cd %s\n", buf+3); else{ if((buf + 3)[0] == '.' && (buf + 3)[1] == '.' && (buf + 3)[2] == 0){ cutChild(currentDir); if(currentDir[0] == 0) isRootDir = 1; continue; } if(isRootDir){ catenate(currentDir, buf + 3); isRootDir = 0; } else{ append(currentDir, '/'); catenate(currentDir, buf + 3); } } continue; } if(fork1() == 0) { int i; int len = strlen(buf); for(i = len + 1; i > 0; i--) { bufCNM[i] = buf[i-1]; } bufCNM[0] = '/'; runcmd(parsecmd(buf)); if(buf[0] != '/') { runcmd(parsecmd(bufCNM)); } exit(); } wait(); } exit(); }
pid_t UTIL_start_process(const char* process, const char* process2, char** argv, const char* prog_name) { /************************************** * * U T I L _ s t a r t _ p r o c e s s * ************************************** * * Functional description * * This function is used to create the specified process, * * Returns Codes: * -1 Process spawn failed. * pid Successful creation. PID is returned. * * Note: Make sure that the argument list ends with a null * and the first argument is large enough to hold the complete * expanded process name. (MAXPATHLEN recommended) * **************************************/ fb_assert(process != NULL); fb_assert(argv != NULL); // prepend Firebird home directory to the program name // choose correct (super/superclassic) image - to be removed in 3.0 Firebird::PathName string = fb_utils::getPrefix(fb_utils::FB_DIR_SBIN, process); if (access(string.c_str(), X_OK) < 0) { string = fb_utils::getPrefix(fb_utils::FB_DIR_SBIN, process2); } if (prog_name) { gds__log("%s: guardian starting %s\n", prog_name, string.c_str()); } // add place in argv for visibility to "ps" strcpy(argv[0], string.c_str()); #if (defined SOLARIS) pid_t pid = fork1(); if (!pid) { if (execv(string.c_str(), argv) == -1) { //ib_fprintf(ib_stderr, "Could not create child process %s with args %s\n", string, argv); } exit(FINI_ERROR); } #else pid_t pid = vfork(); if (!pid) { execv(string.c_str(), argv); _exit(FINI_ERROR); } #endif return (pid); }
/*ARGSUSED*/ static void * forker_monitor( void *arg) { pid_t fpid; char *fmri; char *me = "forker_monitor"; /* wait until forker exits */ fpid = forker_pid; (void) selfcred_pulse(forking_door); _NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG) (me, "forker (pid = %d) exited or crashed, " "killing all child processes\n", fpid); (void) mutex_lock(&forking_lock); forking_door = -1; forker_pid = -1; (void) mutex_unlock(&forking_lock); /* forker exited/crashed, kill all the child processes */ _nscd_kill_all_children(); /* restart forker */ _NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG) (me, "restarting the forker ...\n"); switch (fpid = fork1()) { case (pid_t)-1: _NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG) (me, "unable to fork and start the forker ...\n"); /* enter the maintenance mode */ if ((fmri = getenv("SMF_FMRI")) != NULL) { _NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG) (me, "entering maintenance mode ...\n"); (void) smf_maintain_instance(fmri, SMF_TEMPORARY); } return ((void *)1); break; case 0: _NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG) (me, "execv path = %s\n", execpath); (void) execv(execpath, execargv); exit(0); break; default: _NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_DEBUG) (me, "new forker's pid is %d\n", fpid); forker_pid = fpid; break; } return (NULL); }
static int xorg_backtrace_pstack(void) { pid_t kidpid; int pipefd[2]; if (pipe(pipefd) != 0) { return -1; } kidpid = fork1(); if (kidpid == -1) { /* ERROR */ return -1; } else if (kidpid == 0) { /* CHILD */ char parent[16]; seteuid(0); close(STDIN_FILENO); close(STDOUT_FILENO); dup2(pipefd[1], STDOUT_FILENO); closefrom(STDERR_FILENO); snprintf(parent, sizeof(parent), "%d", getppid()); execle("/usr/bin/pstack", "pstack", parent, NULL); exit(1); } else { /* PARENT */ char btline[256]; int kidstat; int bytesread; int done = 0; close(pipefd[1]); while (!done) { bytesread = read(pipefd[0], btline, sizeof(btline) - 1); if (bytesread > 0) { btline[bytesread] = 0; ErrorFSigSafe("%s", btline); } else if ((bytesread < 0) || ((errno != EINTR) && (errno != EAGAIN))) done = 1; } close(pipefd[0]); waitpid(kidpid, &kidstat, 0); if (kidstat != 0) return -1; } return 0; }
static int daemonize_start(void) { char data; int status; int filedes[2]; pid_t pid; (void) close(0); (void) dup2(2, 1); if (pipe(filedes) < 0) return (-1); (void) fflush(NULL); if ((pid = fork1()) < 0) return (-1); if (pid != 0) { /* * parent */ (void) close(filedes[1]); if (read(filedes[0], &data, 1) == 1) { /* forward ready code via exit status */ exit(data); } status = -1; (void) wait4(pid, &status, 0, NULL); /* daemon process exited before becoming ready */ if (WIFEXITED(status)) { /* assume daemon process printed useful message */ exit(WEXITSTATUS(status)); } else { (void) fprintf(stderr, "daemon process killed or died\n"); exit(EXIT_FAILURE); } } /* * child */ g_pipe_fd = filedes[1]; (void) close(filedes[0]); /* * generic Unix setup */ (void) setsid(); (void) umask(0000); return (0); }
int start1(char *arg) { int status, pid2, kid_pid; printf("start1(): started\n"); pid_z = fork1("XXp1", XXp1, "XXp1", USLOSS_MIN_STACK, 3); printf("start1(): after fork of child %d\n", pid_z); pid2 = fork1("XXp2", XXp2, "XXp2", USLOSS_MIN_STACK, 4); printf("start1(): after fork of child %d\n", pid2); printf("start1(): performing join\n"); kid_pid = join(&status); sprintf(buf,"start1(): exit status for child %d is %d\n", kid_pid, status); printf("%s", buf); printf("start1(): performing join\n"); kid_pid = join(&status); sprintf(buf,"start1(): exit status for child %d is %d\n", kid_pid, status); printf("%s", buf); return 0; }
int start1(char *arg) { int i,status, pid2; char buf[25]; printf("start1(): started\n"); victim = fork1("XXp3", XXp3,"XXp3",USLOSS_MIN_STACK,5); for(i=0;i<N;i++) { sprintf(buf, "%d", i); pid2 = fork1("XXp2", XXp2, buf, USLOSS_MIN_STACK, 4); } join(&status); for(i=0;i<N;i++) { join(&status); } printf("start1(): calling quit\n"); quit(-1); return 0; } /* start1 */
/* * robot_makeChild - Ensure the child process exists. */ static void robot_makeChild() { int pipes[2] = { -1, -1 }; /* * First check if child exists. */ if (child != -1) { /* * Sending signal-0 only does error checking. * If it returns -1 the child does not exist. */ if (kill(child, 0) != -1) { return; } } /* * It does not exist. Set up the pipe, fork, etc. */ #ifdef __linux__ socketpair(AF_UNIX, SOCK_STREAM, 0, pipes); #else pipe(pipes); #endif pipeToChild = pipes[0]; #ifdef __linux__ child = fork(); /* fork1() only re-creates the one thread */ #else child = fork1(); /* fork1() only re-creates the one thread * That's all we need. */ #endif /* The child goes off to handle cmds. * Nothing for the parent to do but continue * about its own business. */ if (child == 0) { /* in child */ int pipeToParent; char arg1[MAX_DIGITS+1]; char * arg2; pipeToParent = dup(pipes[1]); sprintf(arg1, "%d", pipeToParent); arg2 = DisplayString(awt_display); execl(RobotChildExePath, ROBOT_ARG0, arg1, arg2, NULL); perror("Couldn't execl robot child process"); } else { /* in parent */ /* SIGPIPE would make us crash. So we ignore it */ sigignore(SIGPIPE); robot_setupPipe(pipeToChild); } }
int main(void) { static char buf[100]; int fd; // Assumes three file descriptors open. while((fd = open("console", O_RDWR)) >= 0){ if(fd >= 3){ close(fd); break; } } // Read and run input commands. while(getcmd(buf, sizeof(buf)) >= 0){ if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){ // Clumsy but will have to do for now. // Chdir has no effect on the parent if run in the child. buf[strlen(buf)-1] = 0; // chop \n if(chdir(buf+3) < 0) printf(2, "cannot cd %s\n", buf+3); continue; } if(!strncmp(buf,"export PATH",11)){ //if export PATH was called //buf = buf+12; PATH = malloc(10*sizeof(char*)); //allocate memory for the PATH variable memset(PATH, 0, 10*sizeof(char*)); //clean alocated memory - 10 paths max int i; for(i=0;i<10;i++){ PATH[i] = malloc(100); //allocate memory for each path in PATH - 100 chars max memset(PATH[i],0,100); //clean allocated memory } pathInit = 1; //set flag to 1 - initialized int tempIndex = 0; int* beginIndex = &tempIndex; int length = strlen(&(buf[12])); //set the starting point to parse after "export PATH" char** temp = PATH; while(*beginIndex<length-1) //go over the command string and tokenize by delimiter { if(strtok(*temp,&(buf[12]),':',beginIndex)) //if tokenizer returned a string { (temp)++; } } continue; } if(fork1() == 0) { runcmd(parsecmd(buf)); } wait(); } exit(); }
int start2(char *arg) { int kid_status, kidpid; char buffer[20]; int result; USLOSS_Console("start2(): started\n"); mbox_id = MboxCreate(0, 50); USLOSS_Console("\nstart2(): MboxCreate returned id = %d\n", mbox_id); kidpid = fork1("XXp2a", XXp2, "XXp2a", 2 * USLOSS_MIN_STACK, 2); kidpid = fork1("XXp2b", XXp2, "XXp2b", 2 * USLOSS_MIN_STACK, 2); kidpid = fork1("XXp2c", XXp2, "XXp2c", 2 * USLOSS_MIN_STACK, 2); kidpid = fork1("XXp3", XXp3, NULL, 2 * USLOSS_MIN_STACK, 4); kidpid = join(&kid_status); USLOSS_Console("\nstart2(): joined with kid %d, status = %d\n", kidpid, kid_status); kidpid = join(&kid_status); USLOSS_Console("\nstart2(): joined with kid %d, status = %d\n", kidpid, kid_status); kidpid = join(&kid_status); USLOSS_Console("\nstart2(): joined with kid %d, status = %d\n", kidpid, kid_status); kidpid = join(&kid_status); USLOSS_Console("\nstart2(): joined with kid %d, status = %d\n", kidpid, kid_status); result = MboxCondReceive(mbox_id, buffer, 20); if (result == -1) USLOSS_Console("failed to recv from released mailbox ... success\n"); else USLOSS_Console("test failed result = %d\n",result); quit(0); return 0; /* so gcc will not complain about its absence... */ } /* start2 */
int start1(char *arg) { int pid1, kid_status; printf("start1(): started\n"); pid1 = fork1("XXp1", XXp1, "XXp1", USLOSS_MIN_STACK, 5); pid1 = join(&kid_status); printf("XXp1 done; returning...\n"); return 0; /* so gcc will not complain about its absence... */ } /* start1 */