execvp(3)
C library function
Replaces the program in the current process with a command looked up in PATH, its arguments passed in an array terminated by NULL.
#include <unistd.h>
int execvp(const char *file, char *const argv[]);Description
execvp loads another program into the current process and runs it from the start. The code, data and stack of the old program are replaced; the PID does not change, and open file descriptors stay open (except those marked close-on-exec). You almost always call it in a child created by fork, so that the parent carries on.
The p in the name means that file is looked up in the directories listed in the PATH variable, the way the shell does it, unless it contains a /: then it is used as is. The v means the arguments come in an array (a vector). By convention, argv[0] is the command name, and the last element must be NULL. The new program receives the environment of the current process.
The other members of the family change one letter: execlp takes the arguments one by one, ending with (char *) NULL, execv does not search PATH, and the underlying system call, execve, wants an exact path and an explicit environment.
Return value
On success, execvp never returns: there is no calling program left to receive a value. If it does return, it failed, the value is -1 and errno gives the cause: ENOENT when the command cannot be found, EACCES when the file is not executable.
Pitfalls
Everything after
execvpruns only if it fails. Put aperrorand anexitthere, or the child goes on running the parent's code.An argument array without a final
NULLmakesexecvpread past the end of the array.The
printfbuffer is lost in the replacement. Flush it withfflush(stdout)before the call.No such file or directorycan also come from a script whose interpreter does not exist, such as a#!/bin/shline ending in a Windows carriage return.
Example
#include <stdio.h>#include <unistd.h>
int main(int argc, char **argv){ if (argc < 2) { fprintf(stderr, "usage: %s command [arguments]\n", argv[0]); return 2; } execvp(argv[1], argv + 1); perror(argv[1]); return 127;}$ gcc -Wall -Wextra launch.c -o launch$ ./launch echo hello from execvphello from execvp$ ./launch no-such-commandno-such-command: No such file or directory$ echo $?127argv + 1 is already an array in the right format: it starts at the command name and ends with the NULL that the C standard guarantees at argv[argc].
pipe_chain
Write pipe_chain, which starts each command of a list in its own child with execvp and feeds the output of each one to the next.