所谓程序替换就是替换程序所运行的代码,将另一段程序加载到内存,通过页表改变原来的映射关系,重新建立到新程序内存的地址,相当于替换了进程所运行的程序以及所要处理的数据
exec函数族
迷你shell实现
1 #include<stdio.h>
2 #include<errno.h>
3 #include<unistd.h>
4 #include<fcntl.h>
5 #include<stdlib.h>
6 //在minishell中添加重定向
7
8 int main(){
9 while(1){
10 char str[100]={0};
11 printf("yang@localhost:");
12 fflush(stdout);
13 //我们接受字符串通常有两种方式 gets() 和 scanf()
14 //gets()
15 // 1.从标准输入中读取字符串,直到遇见第一个'\n'才读取完成
16 // 2.并且‘\n’并没有在缓冲区当中,会被系统自动遗弃
17 // 3.正是因为它的读取如果条件不满足则一直读取,很容易发生读取越界,所以很不安全
18 //scanf()
19 // 1.从标准输入中读取字符串,当遇见空白字符时读取完成,并且‘\n’会被遗留在缓冲区中
20 // 2.正是因为如此,scanf也时不安全的
21 // 3.解决办法:(正则表达式)
22 // 1.scanf("%[^\n]",str) --- > %[]表示输入字符集,[^\n]表示读取除了‘\n’意外所有
23 // 的字符。及空白字符同样接受
24 // 2.scanf("%[^\n]%*c",str)---->因为除了‘\n’其他都已经被写入数组中,%*c 表示读
25 // 取缓冲区第一个字符,及‘\n’
26 // 4,如果scanf()中有两个参数,均得到正确结果返回2
27 // 如果scanf()中有一个参数,均得到正确结果按返回1
28 // 如果输入错误,返回 EOF
29 if(scanf("%[^\n]%*c",str)!=1){
30 //从标准输入中读取一个字符
31 getchar();
32 continue;
33 }
34 char* ptr=str;
35 int redirect_flag=0;
36 while(*ptr!=0){
37 if(*ptr=='>'){
38 redirect_flag=1;
39 *ptr=0;
40 ptr++;
41 if(*ptr=='>'){
42 redirect_flag=2;
43 *ptr=0;
44 ptr++;
45 }
46 }
47 ptr++;
48 }
49 int index=0;
50 char* ptr1=str;
51 char* buf[100]={0};
52 while(*ptr1!=0){
53 //因为不能记录空白字符,所以需要用的isspace()函数来判断
54 if(!isspace(*ptr1)){
55 buf[index++]=ptr1;
56 while(*ptr1!=0&&!isspace(*ptr1)){
57 ptr1++;
58 }
59 *ptr1='\0';
60 buf[index]=NULL;
61 }
62 ptr1++;
63 }
64 //创建子进程
65 //创建子进程的原因是,在程序被替换后执行完时候会被返回。所以我们可以将程序替换
66 //放到子进程中,即便子进程退出之后,那么父进程可以继续进行进行循环操作
67 if(strcmp(buf[0],"cd")==0){
68 //改变工作路径
69 chdir(buf[1]);
70 continue;
71 }
72 pid_t pid = fork();
73 if(pid<0){
74 perror("fork failure");
75 return -1;
76 }else if(pid==0){
77 int fd=1;
78 if(redirect_flag==1){
79 fd=open("test.txt",O_WRONLY | O_CREAT | O_TRUNC);
80 if(fd<0){
81 exit(-1);
82 }
83 }else if(redirect_flag==2){
84 fd=open("text.txt",O_WRONLY | O_CREAT | O_APPEND);
85 if(fd<0){
86 exit(-1);
87 }
88 }
89 printf("%d\n",redirect_flag);
90 dup2(fd,1);
91 if(execvp(buf[0],buf)<0){
92 //如果程序走到这一步表明已经替换失败
93 exit(0);
94 }
95 }else{
96 wait(NULL);
97 }
98 }
99 return 0;
100 }
101
102