怎么理解程序替换
创建子进程就是为了执行父进程交给他的任务,但是不知道子进程的代码,那么操作系统将可执行程序加载到内存中并且把它的代码替换给子进程,来完成指定的事情,这个过程没有创建子进程。./hello回车就执行hello.c的内容,经过程序替换子进程就会执行打印hello的任务。
底层:
相关替换函数
1、函数调用成功就会加载新的程序从启动代码往后执行,不在返回。
2、调用出错返回-1。
3、exec出错的时候才有返回值。
#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,co;nst char* argv[]); int execvp(const char*file,char* const argv[]); int execve(const char* path,char* const argv[],char* const envp[]);
理解:l(list):表示函数采用参数列表
v(vector):参数用数组
p(path):有p自动搜索环境变量path
e(env):表示自己维护环境变量
函数理解
execl函数:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 int main(){
5 int ret=execl("./hello","./hello",NULL);
6 printf("%d\n",ret);
7 }
我们可以看到他并没有打印出ret的值,这是因为替换hello这个可执行程序成功后就直接返回不会执行到下面,只有出错时才会打印ret
举例:ls -l -t:其中ls也是一个可执行程序,存在于bin目录下
#include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 int main(){
5 int ret=execl("/bin/ls","/bin/ls","-l","-t","-r",NULL);
6 printf("%d\n",ret);
7 }
注意:一旦进行程序替换,那么下面的代码就没有了,所以下面代码无法执行到第二次程序替换,将上面的execl…注释掉
execle函数:
利用hello里面打印环境变量,然后exec.c结合hello来执行,运行hello就会有很多环境变量(由于hello继承了bash的环境变量),再执行exec.c就只有我们自己写的环境变量,这是因为execle函数替换时自己构造环境变量并不继承原有的环境变量
hello.c文件:
1 #include<stdio.h>
2 int main(int argc,char* argv[],char* env[]){
3 (void)argc;
4 (void)argv;
5 size_t i=0;
6 for(;env[i]!=NULL;i++){
7 printf("%s\n",env[i]);
8 }
9 return 0;
10 }
//exec.c文件
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 int main(){
9 const char* env[]={
10 "AAA=hehe",
11 NULL
12 };
13 execle("./hello","./hello",NULL,env);
14 return 0;
15 }
execv函数:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 int main(){
5 const char* env[]={
6 "AAA=haha",
7 NULL
8 };
9 char* argv[]={
10 "/bin/ls","-l","-t","-r",NULL
11 };
12 execv("/bin/ls",argv);
13 return 0;
14 }
execve函数:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 int main(){
5 const char* env[]={
6 "AAA=haha",
7 NULL
8 };
9 const char* argv[]={
10 "./hello","-l","-t","-r",NULL
11 };
12 execve("./hello",argv,env);
13
14 return 0;
15 }
exec函数族例子
其中只有execve是系统调用。