Linux programming -- Process replacement: exec function family, linuxexec
On the Windows platform, we can double-click to run the executable program to make it a process. On the Linux platform, we can./Run to make an executable program a process.
However, if we are already running a program (process), how can we start an external program inside the process, and the kernel reads the external program into the memory, how to execute it into a process? Here we use the exec function family.
Exec function family, as its name implies, is a cluster of functions. In Linux, there are no exec () functions. exec refers to a group of functions, with a total of 6 functions:
#include <unistd.h>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[]);int execve(const char *path, char *const argv[], char *const envp[]);
Among them, only execve () is a real system call, and others are packaged library functions on this basis.
The exec function family provides six typesHow to start another program in the process. The exec function family is used to locate the executable file based on the specified file name or directory name and use it to replace the content of the called process,In other wordsIs to execute an executable file within the calling process.
When a process calls an exec function, the process is completely replaced by a new program, and the new program starts to run from its main function. Because exec is called and no new process is created, the process ID (including the parent process number, process group number, current working directory, etc ......) Not changed. Exec only replaces the body, Data, heap, and stack segments of the current process with another new program (process replacement ).
The six functions in the exec function family seem very complex, but in fact they are very similar in both functions and usage, with only a small difference.
L (list): list of parameter addresses, ending with a null pointer.
V (vector): the address of the array of pointers containing various parameter addresses.
P (path): searches for executable files based on the directory specified by the PATH environment variable.
E (environment): Address of the pointer array containing the environment variable string address.
The exec function family loads and runs the executable program path/file, and passes the arg0 (arg1, arg2, argv [], envp []) parameter to this program.
The exec function family is different from the general function family. The exec function family does not return the result after the function is successfully executed,The code in the exec function family cannot be executed.. Only when the call fails will they return-1. If the call fails, the system proceeds from the call point of the original program.
Execl () sample code:
# Include <stdio. h> # include <unistd. h> int main (int argc, char * argv []) {printf ("before exec \ n");/*/bin/ls: external program, here is the ls executable program in the/bin directory. The path (relative or absolute) ls must be included: meaningless. If you want to transmit parameters to this external program, you must write a string here, as for the arbitrary-a,-l,-h: parameter NULL passed to the external program ls: This must be written, indicates that the parameter passing to the external program ls ends */execl ("/bin/ls", "ls", "-a", "-l", "-h ", NULL); // If execl () is successfully executed, the following execution fails because the current process has been replaced by the executed ls perror ("execl "); printf ("after exec \ n"); return 0 ;}
The running result is as follows:
Execv () sample code:
The usage of execv () and execl () is basically the same. Instead of passing the list parameter, you can use a pointer array.
# Include <stdio. h> # include <unistd. h> int main (int argc, char * argv []) {// the usage of execv () and execl () is basically the same, instead of passing LIST parameters, use the pointer array // execl ("/bin/ls", "ls", "-a", "-l", "-h", NULL ); /* pointer array ls: meaningless. If you need to pass parameters to this external program, you must write a string here. For any string content-a,-l,-h: NULL parameter passed to the external program ls: this parameter must be written to indicate that the parameter passed to the external program ls ends */char * arg [] = {"ls", "-", "-l", "-h", NULL}; // bin/ls: external program. Here is the ls executable program in the/bin directory, PATH (relative or absolute) // arg: the pointer array address previously defined execv ("/bin/ls", arg); perror ("execv "); return 0 ;}
Execlp () or execvp () sample code:
The difference between execlp () and execl () is that the executable program specified by execlp () can have no path name, find the executable program in the directory specified by the Environment Variable PATH. The executable program specified by execl () must carry the PATH name.
# Include <stdio. h> # include <unistd. h> int main (int argc, char * argv []) {// The first parameter "ls" without a path name, find this executable program in the environment variable PATH // use other parameters in the same way as execl () execlp ("ls", "ls", "-a", "-l ", "-h", NULL);/* char * arg [] = {"ls", "-a", "-l", "-h", NULL }; execvp ("ls", arg); */perror ("execlp"); return 0 ;}
Execle () or execve () sample code:
Execle () and execve () change the environment variable of the program started by exec (It only changes the environment variables of the process and does not affect the environment variables of the system.). The default system environment variables are used for programs started by the other four functions.
Execle () sample code:
# Include <stdio. h> # include <unistd. h> # include <stdlib. h> // getenv () int main (int argc, char * argv []) {// getenv () gets the value of the specified environment variable printf ("before exec: USER = % s, HOME = % s \ n ", getenv (" USER "), getenv (" HOME ")); // char * env [] = {"USER = MIKE", "HOME =/tmp", NULL };/*. /mike: external program, the current path of the mike program, through gcc mike. c-o mike compiles mike: It doesn't make sense here. NULL: passing the parameter to the mike program ends env: changing the environment variable of the mike program. to be correct, let the mike program keep only the environment variable of env */execle (". /mike "," mike ", NULL, env);/* char * arg [] = {" mike ", NULL}; execve (". /mike ", arg, env); */perror (" execle "); return 0 ;}
External program, example code of mike. c:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main(int argc, char *argv[]){printf("\nin the mike fun, after exec: \n");printf("USER=%s\n", getenv("USER"));printf("HOME=%s\n", getenv("HOME"));return 0;}
The running result is as follows:
For sample code downloading in this tutorial, click here.