简体   繁体   中英

about fork and execve system call

It is said that fork system call creates a clone of the calling process, and then (usually) the child process issues execve system call to change its image and running a new process. Why this two-step?

BTW, what does execve stand for?

The reason for the two-step is flexibility. Between the two steps you can modify the context of the child process that the newly exec'ed program will inherit.

Some things you may want to change are:

  • File descriptors
  • User/group ID
  • Process group and session IDs
  • Current directory
  • Resource limits
  • Scheduling priority and affinity
  • File creation mask (umask)

If you did not split up fork and exec and instead had a single spawn-like system call, it would need to take arguments for each of these process attributes if you wanted them set differently in a child process. For example, see the argument list to CreateProcess in the Windows API.

With fork/exec, you change whatever inheritable process attributes you want to in the child before you exec the new program.

Setting up file descriptors is one of the more common things to change in a child's process context. If you want to capture the output of a program, you will typically create a pipe in the parent with the pipe(2) system call, and after fork(2)ing, you will close the write end in the parent process and close the read end in the child process before calling execve(2). (You'll also use dup(2) to set the child end of the pipe to be file descriptor 1 (stdout)). This would either be impossible or restrictive in a single system call.

  • exec: Execute new process
  • v : use array of arguments
  • e: Specify as well the environment

Other variations of exec abound:

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
  • l: list arg on function
  • p: use $PATH to locate executable file

Each step is relatively simple.

In Unix, your process has two parts -- a read-only memory area with the application code ("text") and the read-write memory area ("data").

A fork clones the read-write area, leaving the text page alone. You now have two processes running the same code. They differ by a register value -- the return value from fork -- which separates parent from child.

An exec replaces the text page, leaving the data page alone. There are many forms of exec, depending on how much environment information you're passing to it. See http://linux.die.net/man/3/exec for an additional list of variants.

The "exec" family of functions replace the current process image(from where it is called) with a new process image, so the calling image is replaced by the new process image. For eg. if you were to run the 'ls' command from a shell(/bin/sh or /bin/csh) then the shell would fork to a new process which would then execute ls. Once the ls command exits it returns control to the parent process, which in this example is the shell.

If there were no fork functionality then the shell would be replaced by the 'ls' process which upon exit would leave you with an inaccessible terminal since the shell's image in memory was replaced upon the exec call to ls.

For variations in the 'exec' family look at 0x6adb015's answer.

What does execve stand for?

The 6 variations of the exec functions in C are are exec{l,v}{,e,p} . See function prototypes below for details.

Command-line arguments

  • v - Command-line arguments are passed to the function as an array ( v ector) of pointers.
  • l - Command-line arguments are passed individually (a l ist) to the function.

Environment variables (optional)

  • e - An array of pointers to e nvironment variables is explicitly passed to the new process image

Locate the file to be executed (optional)

  • p - Uses the P ATH environment variable to find the file named in the file argument to be executed

int execl (char const *path, char const *arg0, ...);
int execle(char const *path, char const *arg0, ..., char const *envp[]);
int execlp(char const *file, char const *arg0, ...);
int execv (char const *path, char const *argv[]);
int execve(char const *path, char const *argv[], char const *envp[]);
int execvp(char const *file, char const *argv[]);

Source

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM