/* * vfork_return * * Description: "Return" to parent vfork thread() following execve/_exit; * this is done by reassociating the parent process structure * with the task, thread, and uthread. * * Parameters: child_proc Child process * retval System call return value array * rval Return value to present to parent * * Returns: void * * Note: The caller resumes or exits the parent, as appropriate, after * callling this function. */ void vfork_return(proc_t child_proc, int32_t *retval, int rval) { proc_t parent_proc = child_proc->p_pptr; thread_t parent_thread = (thread_t)current_thread(); uthread_t parent_uthread = (uthread_t)get_bsdthread_info(parent_thread); act_thread_catt(parent_uthread->uu_userstate); /* end vfork in parent */ proc_vfork_end(parent_proc); /* REPATRIATE PARENT TASK, THREAD, UTHREAD */ parent_uthread->uu_userstate = 0; parent_uthread->uu_flag &= ~UT_VFORK; /* restore thread-set-id state */ if (parent_uthread->uu_flag & UT_WASSETUID) { parent_uthread->uu_flag |= UT_SETUID; parent_uthread->uu_flag &= UT_WASSETUID; } parent_uthread->uu_proc = 0; parent_uthread->uu_sigmask = parent_uthread->uu_vforkmask; child_proc->p_lflag &= ~P_LINVFORK; child_proc->p_vforkact = (void *)0; thread_set_parent(parent_thread, rval); if (retval) { retval[0] = rval; retval[1] = 0; /* mark parent */ } return; }
/* * vfork_return * * Description: "Return" to parent vfork thread() following execve/_exit; * this is done by reassociating the parent process structure * with the task, thread, and uthread. * * Refer to the ASCII art above vfork() to figure out the * state we're undoing. * * Parameters: child_proc Child process * retval System call return value array * rval Return value to present to parent * * Returns: void * * Notes: The caller resumes or exits the parent, as appropriate, after * calling this function. */ void vfork_return(proc_t child_proc, int32_t *retval, int rval) { task_t parent_task = get_threadtask(child_proc->p_vforkact); proc_t parent_proc = get_bsdtask_info(parent_task); thread_t th = current_thread(); uthread_t uth = get_bsdthread_info(th); act_thread_catt(uth->uu_userstate); /* clear vfork state in parent proc structure */ proc_vfork_end(parent_proc); /* REPATRIATE PARENT TASK, THREAD, UTHREAD */ uth->uu_userstate = 0; uth->uu_flag &= ~UT_VFORK; /* restore thread-set-id state */ if (uth->uu_flag & UT_WASSETUID) { uth->uu_flag |= UT_SETUID; uth->uu_flag &= UT_WASSETUID; } uth->uu_proc = 0; uth->uu_sigmask = uth->uu_vforkmask; proc_lock(child_proc); child_proc->p_lflag &= ~P_LINVFORK; child_proc->p_vforkact = 0; proc_unlock(child_proc); thread_set_parent(th, rval); if (retval) { retval[0] = rval; retval[1] = 0; /* mark parent */ } }