思路
- 定义一个指针数组
char*p[MAXARG]
,用来放参数列表字符数组,将xargs右边的参数先放入:直接读xargs的argv,放入p - 从标准输入得到xargs左边的输入,按行划分成一个一个,拼接到xargs右边的参数上:while循环用
gets
读一行(gets(char* a)
将换行符前的字符读到a上,返回a,如果没读到a为NULL),找到一行输入末尾的换行符,将换行符替换成NULL,放入p的末尾 - exec到子进程上运行。
exec(a,b)
a是命令,b这里在linux系统编程记录过execlp,b是参数列表,argv[0]=命令,从argv[1]开始是命令的参数。
#include "kernel/types.h"
#include "user/user.h"
#include "kernel/param.h"
int main(int argc, char* argv[]){
if(argc == 1){
printf("input not enough\n");
}
// 1、将argv原来的参数列表转移到待拼接参数列表p
char* p[MAXARG];
for(int i =1; i < argc; i++){
p[i-1] = argv[i];// 存到了下标为argc-2
}
p[argc-1] = malloc(512);
//2、读标准输入的参数A,拼接到参数列表p的末尾
char buf[1024];
while(gets(buf,1024)){
if(strlen(buf)>MAXARG) {
printf("input too long\n");
exit(1);
}
p[argc-1] = buf;
// 找到\0前一位,也就是下标为strlen -1处,如果是\n换成NULL
if(p[argc-1][strlen(p[argc-1])-1] == '\n'){
p[argc-1][strlen(p[argc-1])-1] = 0;
}
if(fork() == 0){
exec(argv[1], p);
}
else
wait(0);
}
exit(0);
}
修正过程
- 首先是
gets(a,b)
函数。user.h提供了一个
gets(char* a,int max)
,我之前是直接gets,然后判断gets到的大小。 - 其次是拼接过程,
p[argc-1]
处是放的标准输入参数,strlen(p[argc-1])
得到的是p的最后一个参数字符数组的长度,这个长度不包含\0,因此\0在p[argc-1]的下标是strlen(p[argc-1]),那么\0前一位的下标再-1即可。所以判断if(p[argc-1][strlen(p[argc-1])-1] == '\n')
判断此处是否为换行符,如果是的话,就换成NULL,截断。