1. Functions of exec family functions:
When we use the fork function to create a new process, we often call the exec function to execute another program in the new process. When a process calls the exec function, the process is completely replaced with a new program. Because calling the exec function does not create a new process, the ID of the previous and subsequent processes does not change.
2. Functions:
Execute an executable file inside the calling process. The executable file can be either a binary file or any executable script file under Linux.
3. Function family:
The exec function families are: EXECL, execlp, execle, execv, execvp, and execvpe
Function prototype:
#include <unistd.h> extern char **environ; 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 execvpe(const char *file, char *const argv[],char *const envp[]);
Return value:
The function of the exec function family will not return after successful execution. When the call fails, it will set errno and return - 1, and then execute from the call point of the original program.
Parameter Description:
Path: the path name of the executable file
arg: the parameter carried by the executable program. The first parameter is the name of the executable file, there is no path, and arg must end with NULL
File: if the parameter file contains /, it will be regarded as a PATH name. Otherwise, search for executable files in the directories specified by the PATH environment variable.
exec family function parameters are extremely difficult to remember and distinguish. The characters in the function name will help us:
l: use parameter list
p: Use the file name and look for the executable from the PATH environment
v: You should first construct an array of pointers to each parameter, and then take the address of the array as the parameter of these functions.
e: The envp [] array is added, and the new environment variable is used to replace the environment variable of the calling process
Next, exac functions are classified into four categories with l, p, v and e to illustrate the characteristics of parameters.
1, A class of exac functions with l (l stands for list), including execl, execlp and execle. It is required to specify each command line parameter of the new program as a separate parameter. This parameter table ends with a null pointer.
Take execl function as an example:
//File EXECL c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> //Function prototype: int execl(const char *path, const char *arg,...); int main(void) { printf("before execl\n"); //Executable path = = = executable name = = = parameter list = = = must end with NULL if(execl("./echoarg","echoarg","abc",NULL) == -1) { printf("execl failed!\n"); //perror can type the reason for the error code perror("why"); } printf("after execl\n"); return 0; }
//File echoarg c
#include <stdio.h> int main(int argc,char *argv[]) { int i = 0; for(i = 0; i < argc; i++) { printf("argv[%d]: %s\n",i,argv[i]); } return 0; }
Experimental results:
ubuntu:~/test/exec_test$ ./execl before execl argv[0]: echoarg argv[1]: abc
Experiment Description:
Let's compile echoarg. XML with gcc first c. Generate an executable file echoarg and put it in the current path directory. The file echoarg is used to print command line parameters. Then compile execl C and execute execl executable. Use execl to find and execute echoarg and replace the current process main, so "after execl" is not printed on the terminal.
#include <stdio.h> #include <stdlib.h> #include <unistd.h> //Function prototype: int execl(const char *path, const char *arg,...); int main(void) { printf("before execl****\n"); if(execl("/bin/ls","ls","-l",NULL) == -1) { printf("execl failed!\n"); } printf("after execl*****\n"); return 0; }
hcc@ubuntu:~/LinuxSystemProgramming/PROCESS$ ./a.out before execl total 52 -rwxr-xr-x 1 hcc hcc 8384 Jul 25 04:02 a.out -rw-r--r-- 1 hcc hcc 447 Jul 24 20:25 demo1.c -rw-r--r-- 1 hcc hcc 475 Jul 24 20:53 demo2.c -rw-r--r-- 1 hcc hcc 652 Jul 24 21:26 demo3.c -rw-r--r-- 1 hcc hcc 330 Jul 25 03:39 demo4.c -rw-r--r-- 1 hcc hcc 322 Jul 25 04:02 demo5.c -rw-r--r-- 1 hcc hcc 323 Jul 24 19:51 demo.c -rwxr-xr-x 1 hcc hcc 8304 Jul 25 03:21 echoarg -rw-r--r-- 1 hcc hcc 139 Jul 25 03:20 echoarg.c
2. A class of exac functions with p, including execlp, execvp and execvpe. If the parameter file contains /, it will be regarded as the PATH name. Otherwise, search for the executable file in each directory specified by the PATH environment variable. For example, PATH=/bin:/usr/bin
#include <stdio.h> #include <stdlib.h> #include <unistd.h> //Function prototype: int execl(const char *path, const char *arg,...); int main(void) { printf("before execl****\n"); if(execl("ps","ps","-l",NULL) == -1) { printf("execl failed!\n"); } printf("after execl*****\n"); return 0; }
Experimental results:
ubuntu:~/test/exec_test$ gcc execl_no_path.c -o execl_no_path ubuntu:~/test/exec_test$ ./execl_no_path before execl**** execl failed! after execl*****
In the above example, execl cannot find the executable file because the parameter has no path.
Let's take another example to compare:
//File execlp c #include <stdio.h> #include <stdlib.h> #include <unistd.h> //Function prototype: int execlp(const char *file, const char *arg,...); int main(void) { printf("before execlp****\n"); if(execlp("ps","ps","-l",NULL) == -1) { printf("execlp failed!\n"); } printf("after execlp*****\n"); return 0; }
Experimental results:
ubuntu:~/test/exec_test$ gcc execlp.c -o execlp ubuntu:~/test/exec_test$ ./execlp before execlp**** F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 R 1048 35976 74920 0 80 0 - 2860 - pts/4 00:00:00 ps 0 S 1048 74920 74916 0 80 0 - 7579 wait pts/4 00:00:00 bash
It can be seen from the above experimental results that the above exaclp function has p, so the executable ps can be found through the environment variable PATH
3, For a class of exac functions with v and without l, including execv, execvp and execve, we should first construct a pointer array pointing to each parameter, and then take the address of the array as the parameter of these functions.
For example, char *arg [], and the last element of arg must be NULL. For example, char *arg [] = {"ls", - l ", NULL};
Let's take execvp function as an example:
//File execvp c #include <stdio.h> #include <stdlib.h> #include <unistd.h> //Function prototype: int execvp(const char *file, char *const argv []); int main(void) { printf("before execlp****\n"); char *argv[] = {"ps","-l",NULL}; if(execvp("ps",argv) == -1) { printf("execvp failed!\n"); } printf("after execlp*****\n"); return 0; }
Experimental results:
ubuntu:~/test/exec_test$ gcc execvp.c -o execvp
ubuntu:~/test/exec_test$ ./execvp
before execlp****
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 R 1048 63491 74920 0 80 0 - 2860 - pts/4 00:00:00 ps
0 S 1048 74920 74916 0 80 0 - 7579 wait pts/4 00:00:00 bash
4, A class of exac functions with E, including execle and execvpe, can pass a pointer to the environment string pointer array. Parameters such as char *env_init[] = {“AA=aa”,”BB=bb”,NULL}; With e indicates that the function takes the envp [] array instead of the current environment.
Take the execle function as an example:
//File execle c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//Function prototype: int execle(const char *path, const char *arg,..., char * const envp []);
char *env_init[] = {"AA=aa","BB=bb",NULL};
int main(void)
{
printf("before execle****\n");
if(execle("./bin/echoenv","echoenv",NULL,env_init) == -1)
{
printf("execle failed!\n");
}
printf("after execle*****\n");
return 0;
}
//File echoenv c
#include <stdio.h>
#include <unistd.h>
extern char** environ;
int main(int argc , char *argv[])
{
int i;
char **ptr;
for(ptr = environ;*ptr != 0; ptr++)
printf("%s\n",*ptr);
return 0;
}
Experimental results:
ubuntu:~/test/exec_test$ gcc execle.c -o execle
ubuntu:~/test/exec_test$ ./execle
before execle****
AA=aa
BB=bb
We first write a program that displays all the environment tables, named echoenv c. Then compile it into an executable file and put it in/ bin directory. Then run the executable execle and find that the environment variables we set are indeed passed in.
Original link: https://blog.csdn.net/u014530704/article/details/73848573