首页 > 其他分享 >OS Lab 1.6 xargs (moderate)

OS Lab 1.6 xargs (moderate)

时间:2022-11-25 13:32:41浏览次数:45  
标签:kernel 1.6 读取 exec xargs 参数 缓冲区 moderate OS


1

实验要求


编写一个简单的 UNIX ​​xargs​​​ 程序,从标准输入中读取行并为每一行运行一个命令,将该行作为命令的参数提供。你的解决方案应该放在 ​​user/xargs.c​​ 中。


2

实验提示


  • 使用 ​​fork()​​ 和 ​​exec()​​ 在每一行输入上调用命令。在 ​​parent​​ 中使用 ​​wait()​​ 等待 ​​child​​ 完成命令。
  • 要读取单个输入行,请一次读取一个字符,直到出现换行符(​​'\n'​​)。
  • ​kernel/param.h​​​ 声明了 ​​MAXARG​​ ,如果你需要声明一个 ​​argv​​ 数组,这可能很有用。
  • 将程序添加到 ​​Makefile​​ 的 ​​UPROGS​​ 中。
  • 文件系统的变化在 ​​qemu​​ 的运行中持续存在。使用 ​​make clean​​ 然后再 ​​make qemu​​ 让一个干净的文件系统运行。


3

实验思路


  1. 根据提示,我们需要调用 ​​fork()​​ 创建子进程,和调用 ​​exec()​​ 执行命令。我们知道要从标准输入中读取行并为每行运行一个命令,且将该行作为命令的参数。即把输入的字符放到命令后面,然后调用 ​​exec()​​ 。我们可以依次处理每行,根据空格符和换行符分割参数,调用子进程执行命令。
  2. 首先,我们定义一个字符数组,作为子进程的参数列表,其大小设置为 ​​kernel/param.h​​ 中定义的 ​​MAXARG​​ ,用于存放子进程要执行的参数。而后,建立一个索引便于后面追加参数,并循环拷贝一份命令行参数,即拷贝 ​​xargs​​ 后面跟的参数。创建缓冲区,用于存放从管道读出的数据。
  3. 然后,循环读取管道中的数据,放入缓冲区,建立一个新的临时缓冲区存放追加的参数。把临时缓冲区追加到子进程参数列表后面。并循环获取缓冲区字符,当该字符不是换行符时,直接给临时缓冲区;否则创建一个子进程,把执行的命令和参数列表传入 ​​exec()​​ 函数中,执行命令。当然,这里一定要注意,父进程一定得等待子进程执行完毕。


4

实验代码


// Lab Xv6 and Unix utilities
// xargs.c

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/param.h"

#define MAXN 1024

int
main(int argc, char *argv[])
{
// 如果参数个数小于 2
if (argc < 2) {
// 打印参数错误提示
fprintf(2, "usage: xargs command\n");
// 异常退出
exit(1);
}
// 存放子进程 exec 的参数
char * argvs[MAXARG];
// 索引
int index = 0;
// 略去 xargs ,用来保存命令行参数
for (int i = 1; i < argc; ++i) {
argvs[index++] = argv[i];
}
// 缓冲区存放从管道读出的数据
char buf[MAXN] = {"\0"};

int n;
// 0 代表的是管道的 0,也就是从管道循环读取数据
while((n = read(0, buf, MAXN)) > 0 ) {
// 临时缓冲区存放追加的参数
char temp[MAXN] = {"\0"};
// xargs 命令的参数后面再追加参数
argvs[index] = temp;
// 内循环获取追加的参数并创建子进程执行命令
for(int i = 0; i < strlen(buf); ++i) {
// 读取单个输入行,当遇到换行符时,创建子线程
if(buf[i] == '\n') {
// 创建子线程执行命令
if (fork() == 0) {
exec(argv[1], argvs);
}
// 等待子线程执行完毕
wait(0);
} else {
// 否则,读取管道的输出作为输入
temp[i] = buf[i];
}
}
}
// 正常退出
exit(0);
}


5

实验结果


在 ​​Makefile​​​ 文件中, ​​UPROGS​​​ 项追加一行 ​​$U/_xargs\​​ 。编译并运行 xv6 进行测试。

$ make clean
...
$ make qemu
...
init: starting sh
$ echo hello too | xargs echo bye
bye hello too

退出 xv6 ,运行单元测试检查结果是否正确。

./grade-lab-util xargs

通过测试样例。

make: 'kernel/kernel' is up to date.
== Test xargs == xargs: OK (1.8s)



标签:kernel,1.6,读取,exec,xargs,参数,缓冲区,moderate,OS
From: https://blog.51cto.com/u_15891283/5886576

相关文章