exec类函数的作用:在执行完fork函数之后,希望子进程可以执行其他现有的代码(不用再写一遍,),就可以用exec类型函数替换子进程里的代码.
exec类函数把当前进程映像替换成新的进程文件,而且该新程序通常从main函数处开始执行。进程ID并不改变。六个exec函数的区别在于:(a)待执行的程序文件是由文件名还是由路径名指定;(b)新程序的参数是一一列出还是由一个指针数组来引用;(c)把调用进程的环境传递给新程序还是给新程序指定新的环境。
替换过程:
1.首先用磁盘中已有的代码和数据
2.然后更新堆栈
接下来是exec簇里的函数 包含#include <unistd.h>
所有的函数的返回值都为int型,如果调用成功直接执行替换的函数,不在返回,如果调用失败返回-1;
1.int execl(const char *path, const char *arg, ...);
path:需要替换的函数(要包含路径)
arg:传递可执行程序的命令行参数,第一个必须是可执行程序本身,后面的参数是命令行参数,以逗号隔开,命令行参数传递完后,最后一个是NULL
#include<stdio.h>
2 #include<unistd.h>
3 int main()
4 {
5 pid_t a=fork();
6 if(a<0)
7 {
8 return 0;
9 }
10 else if(a==0)
11 {
12 //child
W> 13 int aa=execl("/usr/bin/ls","ls",NULL);
14 printf("i am child");
15 }
16 else
17 {
18 printf("i am parent");
19 }
20 return 0;
21
22 }
运行结束后子进程就会调用ls,打印出当前目录下的内容
2int execlp(const char *file, const char *arg, ...);
file:代表可替换的函数,和path不同的是file参数不需要带路径
arg:和上面相同
3int execle(const char *path, const char *arg, ..., char * const envp[]);
path:和一号函数的path的意义相同
arg:和上面相同
envp:自己组织的环境变量
#include<stdio.h>
2 #include<unistd.h>
3 int main()
4 {
5 pid_t a=fork();
6 if(a<0)
7 {
8 return 0;
9 }
10 else if(a==0)
11 {
12 //child
13 extern char**environ;
W> 14 int aa=execle("/usr/bin/ls","ls",NULL,environ);
15 printf("i am child");
16 }
17 else
18 {
19 printf("i am parent");
20 }
21 return 0;
22
23 }
运行结果都是展示当前目录下的文件;
extern char**environ是指向的是组织环境变量的字符指针数组;
环境变量的组织方式
环境变量是以字符指针数组组织的,每个数组都能指向一个环境变量,最后一个为NULL,当读取到NULL是进程就知道环境变量已经读取完毕了
4 int execv(const char *path, char *const argv[]);
path:和前面的path意义相同
argv:是一个字符指针数组,传参时,就不能像前面的函数是可变参数列表.这个参数需要在外面将参数写入字符指针数组里.
#include<stdio.h>
2 #include<unistd.h>
3 int main()
4 {
5 pid_t a=fork();
6 if(a<0)
7 {
8 return 0;
9 }
10 else if(a==0)
11 {
12 //child
13 char*arr[10]={0};
W> 14 arr[0]="ls";
15 arr[1]=NULL;
W> 16 int aa=execv("/usr/bin/ls",arr);
17 printf("i am child");
18 }
19 else
20 {
21 printf("i am parent");
22 }
23 return 0;
24
25 }
5int execvp(const char *file, char *const argv[]);
参数含义上文有解释
#include<stdio.h>
2 #include<unistd.h>
3 int main()
4 {
5 pid_t a=fork();
6 if(a<0)
7 {
8 return 0;
9 }
10 else if(a==0)
11 {
12 //child
13 char*arr[10]={0};
W> 14 arr[0]="ls";
15 arr[1]=NULL;
W> 16 int aa=execvp("ls",arr);
17 printf("i am child");
18 }
19 else
20 {
21 printf("i am parent");
22 }
23 return 0;
24
25 }
6 int execve(const char *path, char *const argv[], char *const envp[]);
#include<stdio.h>
2 #include<unistd.h>
3 int main()
4 {
5 pid_t a=fork();
6 if(a<0)
7 {
8 return 0;
9 }
10 else if(a==0)
11 {
12 //child
13 char*arr[10]={0};
W> 14 arr[0]="ls";
15 arr[1]=NULL;
entern char**environ;
W> 16 int aa=execve("/usr/bin/ls",arr,environ);
17 printf("i am child");
18 }
19 else
20 {
21 printf("i am parent");
22 }
23 return 0;
24
25 }
总结:
exec函数簇里的函数 带有l,第二个参数以可变参数传递....带p第一个参数,也就是需要替换的函数可以不带路径....带有v的函数,第二个参数以字符指针数组的方式进行传递...带有e,自己组织环境变量传给第三个参数.