4 Execute programs - Aryalexa/42-pipex GitHub Wiki
Having several processes run the same program is only occasionally useful (when using only fork). But the child can execute another program using one of the exec
functions; see Executing a File.
An exec
function executes programs/executables and can receive arguments for the program. It does not execute commands like a terminal would (ls | wc
would not work).
The program that the process is executing is called its process image. Starting execution of a new program causes the process to forget all about its previous process image; when the new program exits, the process exits too, instead of returning to the previous process image.
A successful exec
call does not return. If it returns, something went wrong and it returns a -1.
int pid = fork();
if (pid == -1) // fork error
exit();
if (pid == 0) {
exec(..) // any of the exec family functions
printf("exec error\n"); // not reached if the exec successes
} else {
wait(NULL); // wait for child
printf("Success - the exec finished");
}
The wait
parameter is used to captured the status of the child process and tells you if it terminated normally or not.
-
WIFEXITED(status)
: did the process exit normally? (as opposed to being signaled). -
WEXITSTATUS(status) == 0
: did the process exit with exit code 0 (aka "success")
// the parent
int status;
wait(&status);
if (WIFEXITED(status)) {
int status_code = WEXITSTATUS(status);
if (status_code == 0)
printf("success\n");
else
printf("failure\n");
}
When any of these exec
functions fail, the errno
is assigned an error value automatically, and using perror
will print the corresponding error message.
There's a family of exec
functions where
-
v
/l
- stands for the format the arguments are given: vector or list -
p
- stands for path -
e
- stands for environment
int execl(const char *path, const char *arg0, ..., NULL);
- It needs the entire path of the command (on shell use
where <cmd>
orwhich <cmd>
to print the path) - It needs the arguments for the command as a list, arg0 is the name of the program and the list is null terminated.
// we want: ping -c 3 google.com
execl("/sbin/ping", "/sbin/ping", "-c", "3", "google.com", NULL);
int execlp(const char *file, const char *arg0, ..., NULL);
same as the above but the p
means the execution should use the PATH variable where the ping path is going to be found, so we can use just the name of the command and not the entire path.
// we want: ping -c 3 google.com
execlp("ping", "ping", "-c", "3", "google.com", NULL);
int execvp(const char *file, char *const argv[]);
- It expects the arguments as an array of arguments.
- It uses the PATH variable so we can use the names of the programs and not their whole paths.
char *argv[] = {"ping", "-c", "3", "google.com", NULL}
execvp("ping", argv);
int execve(const char *path, char *const argv[], char *const envp[]);
- It needs the path of the programs.
- It expects the arguments as an array or vector.
- The
e
means environment, a set of variables that we can pass to the functions. So the function can access this variables during its execution.
The
main
function actually receives an environment tooint main(int argc, char *argv[], char *envp[])
char *argv[] = {"/sbin/ping", "-c", "3", "google.com", NULL}
char *env[] = {"TEST=env var", NULL}; // create your own env, or use/modify the one from main.
execve("/sbin/ping", argv, env);
All these other exec functions are combinations of the 4 letters v
/l
, p
and e
.