一、进程程序替换
用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往强调一种exec函数执行另一个程序。当进程调用exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动历程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。
替换函数
#include<stdio.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[]);
相关解释:
(1)这些函数如果调用成功则加载新的程序从启动代码开始新的执行,不再返回
(2)如果调用出错则返回-1
(3)exec函数只有出错的返回值而没有成功的返回值
函数规律:
·函数名不带p:第一个参数必须是程序的相对路径和绝对路径
·函数名带e:可以把一份新的环境变量传给它,其他exec函数仍使用当前的环境变量表执行新程序
·函数名带l:要求将新程序的每个命令行参数都当做第一个参数传给它,命令行参数的个数是可变的,而且最后一个可变参数应该是NULL
·函数名带v:应该先构造一个指向各参数的指针数组,然后将该数组的首地址当做参数传给它,数组中的最后一个指针也应该是NULL
参照下表:
例:exec函数
1、简单的hello.c文件
1 #include<stdio.h>
2 int main()
3 {
4 printf("hello word!\n");
5 return 0;
6 }
2、exec函数
1 #include<stdio.h>
2 #include<unistd.h>
3
4 int main()
5 {
6 char *const argv[] = {"ps","ef",NULL};
7 char *const envp[] = {"PATH=/bin:/usr/bin","TERM=console",NULL};
8
9 execl("/bin/ps","ps","-ef",NULL);
10
11 execlp("ps","ps","-ef",NULL);
12
13 execle("ps","ps","-ef",NULL,envp);
14
15 execv("/bin/ps",argv);
16
17 execvp("ps",argv);
18
19 execve("/bin/ps",argv,envp);
20
21 exit(0);
22 }
只有execve是真正的系统调用,其他5个函数最终都调用execve
二、根据exec函数做一个简易的shell
1 #include<unistd.h>
2 #include<sys/wait.h>
3 #include<stdio.h>
4 #include<string.h>
5 #include<stdlib.h>
6
7 char *argv[8];
8 int argc = 0;
9
10 void do_parse(char *buf)
11 {
12 int i;
13 int status = 0;
14 for(argc = i = 0;buf[i];i++){
15 if(!isspace(buf[i]) && status == 0){
16 argv[argc++] = buf+i;
17 status = 1;
18 }
19 else if(isspace(buf[i])){
20 status = 0;
21 buf[i] = 0;
22 }
23 }
24 }
25 void do_execute()
26 {
27 pid_t pid = fork();
28 switch(pid){
29 case -1:
30 perror("fork");
31 exit(EXIT_FAILURE);
32 break;
33 case 0:
34 execvp(argv[0],argv);
35 perror("execvp");
36 exit(EXIT_FAILURE);
37 default:
38 {
39 int set;
40 while(wait(&set) != pid)
41 ;
42 }
43 }
44 }
45 int main()
46 {
47 char buf[1024] = {};
48 while(1){
49 printf("myshell>");
50 scanf("%[^\n]%*c",buf);
51 do_parse(buf);
52 do_execute();
53 }
54 }
![](https://i-blog.csdnimg.cn/blog_migrate/fcbbd28ce59399837736cb8c836f2cdb.png)