int execlp( /* SYNOPSIS */ const char *file, const char *arg, ...) /* FUNCTION Executes a file with given name. The search paths for the executed file are paths specified in the PATH environment variable. INPUTS file - Name of the file to execute. arg - First argument passed to the executed file. ... - Other arguments passed to the executed file. RESULT Returns -1 and sets errno appropriately in case of error, otherwise doesn't return. NOTES EXAMPLE BUGS SEE ALSO execve(), execl(), execv(), execvp() INTERNALS ******************************************************************************/ { va_list args; char *const *argv; va_start(args, arg); if(!(argv = __exec_valist2array(arg, args))) { errno = ENOMEM; return -1; } va_end(args); APTR id = __exec_prepare(file, 1, argv, environ); __exec_cleanup_array(); if (!id) return -1; __exec_do(id); assert(0); /* Should not be reached */ return -1; } /* execlp() */
int execv( /* SYNOPSIS */ const char *path, char *const argv[]) /* FUNCTION Executes a file located in given path with specified arguments. INPUTS path - Pathname of the file to execute. argv - Array of arguments given to main() function of the executed file. RESULT Returns -1 and sets errno appropriately in case of error, otherwise doesn't return. NOTES EXAMPLE BUGS SEE ALSO execve(), execl(), execlp(), execvp() INTERNALS ******************************************************************************/ { char ***environptr = __posixc_get_environptr(); char **environ = (environptr != NULL) ? *environptr : NULL; APTR id = __exec_prepare(path, 0, argv, environ); if (!id) return -1; __exec_do(id); assert(0); /* Should not be reached */ return -1; } /* execv() */
int execvp( /* SYNOPSIS */ const char *file, char *const argv[]) /* FUNCTION Executes a file with given name. The search paths for the executed file are paths specified in the PATH environment variable. INPUTS file - Name of the file to execute. argv - Array of arguments given to main() function of the executed file. RESULT Returns -1 and sets errno appropriately in case of error, otherwise doesn't return. NOTES EXAMPLE BUGS SEE ALSO execve(), execl(), execlp(), execv() INTERNALS ******************************************************************************/ { APTR id = __exec_prepare(file, 1, argv, environ); if(!id) return -1; __exec_do(id); assert(0); return -1; } /* execvp() */
LONG launcher() { D(bug("launcher: Entered child launcher\n")); struct Task *this = FindTask(NULL); struct vfork_data *udata = this->tc_UserData; BYTE child_signal; struct Library *aroscbase = NULL; GetIntETask(this)->iet_startup = GetETask(this)->et_Result2 = AllocVec(sizeof(struct aros_startup), MEMF_ANY | MEMF_CLEAR); /* Allocate signal for parent->child communication */ child_signal = udata->child_signal = AllocSignal(-1); D(bug("launcher: Allocated child signal: %d\n", udata->child_signal)); if(udata->child_signal == -1) { /* Lie */ udata->child_errno = ENOMEM; Signal(udata->parent, 1 << udata->parent_signal); return -1; } if(__register_init_fdarray(udata->ppriv->acpd_fd_array, udata->ppriv->acpd_numslots)) aroscbase = OpenLibrary((STRPTR) "arosc.library", 0); if(!aroscbase) { FreeSignal(child_signal); udata->child_errno = ENOMEM; Signal(udata->parent, 1 << udata->parent_signal); return -1; } udata->cpriv = __get_arosc_privdata(); udata->cpriv->acpd_parent_does_upath = udata->ppriv->acpd_doupath; udata->cpriv->acpd_flags |= DO_NOT_CLONE_ENV_VARS; if(setjmp(__aros_startup_jmp_buf) == 0) { /* Setup complete, signal parent */ D(bug("launcher: Signaling parent that we finished setup\n")); Signal(udata->parent, 1 << udata->parent_signal); D(bug("launcher: Child waiting for exec or exit\n")); Wait(1 << udata->child_signal); if(udata->child_executed) { APTR exec_id; BPTR dir; D(bug("launcher: child executed\n")); /* Set current dir to parent's current dir */ dir = DupLock(((struct Process *)udata->parent)->pr_CurrentDir); UnLock(CurrentDir(dir)); /* Don't mind updating aroscbase->acb_startup_cd_changed as we will exit from process after __exec_do has finished */ /* Filenames passed from parent obey parent's __doupath */ __doupath = udata->cpriv->acpd_parent_does_upath; D(bug("launcher: __doupath == %d for __exec_prepare()\n", __doupath)); exec_id = udata->exec_id = __exec_prepare( udata->exec_filename, udata->exec_searchpath, udata->exec_argv, udata->exec_envp ); udata->child_errno = errno; /* Clear __doupath again, command will set it if wanted */ __doupath = 0; D(bug("launcher: informing parent that we have run __exec_prepare\n")); /* Inform parent that we have run __exec_prepare */ Signal(udata->parent, 1 << udata->parent_signal); /* Wait 'till __exec_do() is called on parent process */ D(bug("launcher: Waiting parent to get the result\n")); Wait(1 << udata->child_signal); D(bug("launcher: informing parent that we won't use udata anymore\n")); /* Inform parent that we won't use udata anymore */ Signal(udata->parent, 1 << udata->parent_signal); if (exec_id) { D(bug("launcher: executing command\n")); __exec_do(exec_id); assert(0); /* Should not be reached */ } else { D(bug("launcher: exit because execve returned with an error\n")); _exit(0); } } else { D(bug("launcher: informing parent that we won't use udata anymore\n")); /* Inform parent that we won't use udata anymore */ Signal(udata->parent, 1 << udata->parent_signal); } } else { D(bug("launcher: freeing child_signal\n")); FreeSignal(child_signal); CloseLibrary(aroscbase); } return 0; }