Process (exec function family)

Posted by brockie99 on Mon, 18 Oct 2021 22:14:14 +0200

In the previous section, we know that the child process is a replica of the parent process, and the program executed by the child process is the same as that of the parent process (the program after fork()), so if you can only rely on the code of the parent process, the role of the child process is not very great.
Is there any way to prevent the child process from executing the code of the parent process, but to let the child process execute other code? This uses the exec function family.

exec function family

There are several functions in the exec function family:
int execl(const char *path,const char *arg,...);
int execlp(const char *file,const char *arg,...);
int execv(const char *path,char *const argv[] );
int execvp(const char *file,char *const argv[]);
int execle(const char *path,const char *arg,...,char *const envp[]);
int execve(const char *pathchar *const argv[],char *const envp[]);
Although the six functions in the exec function family have some differences in syntax, their functions are basically the same;
So what's the difference between them?
In fact, the main difference is that the fifth l and v behind exec and the sixth e and p. who are these four sacred and what unique skills do they have
l: Parameters are passed by enumerating one by one;
v: The parameter is passed as the method of constructing pointer array;
e: New process environment variables can be passed;
p: The search method in the executable file is the file name;
(Note: using the exec function will replace the program in the process, so other functions will not be executed except the exec function)

Usage of execl

code

#include<stdio.h>
#include<unistd.h>


int main(){

	pid_t pid;

	pid = fork();

	if(pid < 0){
		perror("fork");
		return 0;
	}else if(pid > 0){
		printf("my pid %d son pid %d\n",getpid(),pid);
		while(1);
	}else{
		execl("/home/ubuntu-14-zs/1024/pid/exec_test","exec_test",NULL); //The child process calls execl()
		while(1);
	}

}

execl needs to write the full path and name of the executing program (it can also be written as execl("./pid_test", "pid_test", NULL) in the current directory);

Exec executed by execl_ The test code is as follows

#include<stdio.h>

int main(){
int i,j;
for(i = 0;i <= 9;i++){
	for(j = 0;j <= 9;j++){
		if(j <= i){
			printf("%2d*%2d=%2d",i,j,i*j);
			}
		}
puts("");
	}
printf("this is exec_test\n");
}

exec_test execution results

ubuntu-14-zs@ubuntu:~/1024/pid$ ./exec_test
 0* 0= 0
 1* 0= 0 1* 1= 1
 2* 0= 0 2* 1= 2 2* 2= 4
 3* 0= 0 3* 1= 3 3* 2= 6 3* 3= 9
 4* 0= 0 4* 1= 4 4* 2= 8 4* 3=12 4* 4=16
 5* 0= 0 5* 1= 5 5* 2=10 5* 3=15 5* 4=20 5* 5=25
 6* 0= 0 6* 1= 6 6* 2=12 6* 3=18 6* 4=24 6* 5=30 6* 6=36
 7* 0= 0 7* 1= 7 7* 2=14 7* 3=21 7* 4=28 7* 5=35 7* 6=42 7* 7=49
 8* 0= 0 8* 1= 8 8* 2=16 8* 3=24 8* 4=32 8* 5=40 8* 6=48 8* 7=56 8* 8=64
 9* 0= 0 9* 1= 9 9* 2=18 9* 3=27 9* 4=36 9* 5=45 9* 6=54 9* 7=63 9* 8=72 9* 9=81
this is exec_test

Code execution results of execl

ubuntu-14-zs@ubuntu:~/1024/pid$ ./pid_test3
my pid 8155 son pid 8156
 0* 0= 0
 1* 0= 0 1* 1= 1
 2* 0= 0 2* 1= 2 2* 2= 4
 3* 0= 0 3* 1= 3 3* 2= 6 3* 3= 9
 4* 0= 0 4* 1= 4 4* 2= 8 4* 3=12 4* 4=16
 5* 0= 0 5* 1= 5 5* 2=10 5* 3=15 5* 4=20 5* 5=25
 6* 0= 0 6* 1= 6 6* 2=12 6* 3=18 6* 4=24 6* 5=30 6* 6=36
 7* 0= 0 7* 1= 7 7* 2=14 7* 3=21 7* 4=28 7* 5=35 7* 6=42 7* 7=49
 8* 0= 0 8* 1= 8 8* 2=16 8* 3=24 8* 4=32 8* 5=40 8* 6=48 8* 7=56 8* 8=64
 9* 0= 0 9* 1= 9 9* 2=18 9* 3=27 9* 4=36 9* 5=45 9* 6=54 9* 7=63 9* 8=72 9* 9=81
this is exec_test


Through the ps command, we find that the child process cannot be found, so let's ps exec_test try

Here we find the subprocess 8156, and the subprocess has ended, although in PID_ In test3, we added while (1) to the subprocess, but after exec, the program was completely replaced and did not execute while (1);

Usage of execlp

The usage of execlp is basically the same as that of execl. const char *path is different. Execlp will automatically find the files to be executed in the PATH. The information contained in the PATH can be viewed through echo $PATH
Put the above procedure

execl("/home/ubuntu-14-zs/1024/pid/exec_test","exec_test",NULL);
//Change to
execlp("exec_test","exec_test",NULL);

execlp calls exec_test failed. How to solve it?
We can, exec_ Add the PATH of test to the PATH;
You can change the PATH at the terminal

ubuntu-14-zs@ubuntu:~/1024/pid$ export PATH=./

Then it is OK to execute the program, but this method needs to re execute export PATH =. When opening another terminal to execute the program/

Usage of execle

execle can solve the problem that execlp cannot find the program to be executed because of the file path;

code

#include<stdio.h>
#include<unistd.h>


int main(){

	pid_t pid;

	pid = fork();

	char *envp[] = {"PATH = ./",NULL};//Configure a path for execle

	if(pid < 0){
		perror("fork");
		return 0;
	}else if(pid > 0){
		printf("my pid %d son pid %d\n",getpid(),pid);
		while(1);
	}else{
		execle("exec_test","exec_test",NULL,envp);
		while(1);
	}

}

results of enforcement

In this way, the execution is successful and the problem of execlp is solved;

summary

The functions of exec function family are similar. Only the above are listed, and the rest are similar. You can explore them.

Topics: C Process