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

execl

int execl(const char *path, const char *arg0, ..., NULL);

  • It needs the entire path of the command (on shell use where <cmd> or which <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);

execlp

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);

execvp

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);

execve

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 too int 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);

execle, execv, ...

All these other exec functions are combinations of the 4 letters v/l, p and e.

⚠️ **GitHub.com Fallback** ⚠️