【MIT 6.S081】Lab1: Xv6 and Unix utilities
创始人
2024-05-31 04:35:46
0

Util

  • 概述
  • ```sleep```
  • ```pingpong```
  • ```primes```
  • ```find```
  • ```xargs```

本Lab包括五个应用程序的实现,初步熟悉系统调用接口。
用时约8h(我太菜辣)

本Lab包括五个简单程序的实现,初步熟悉系统调用接口。
笔者用时约6h(我太菜辣)

概述

根据文档说明,我们需要把写的每个程序文件放在user文件夹下,并且在MakeFileUPROGS添加相应的程序名,这样子就可以在qemu中直接用命令行指令调用相应的程序啦。如下图所示。
在这里插入图片描述

sleep

sleep程序接收一个参数,调用库函数sleep进行睡眠即可,没啥好说滴。

#include "kernel/types.h"
#include "user/user.h"int main(int argc, char* argv[]) 
{if (argc != 2) { fprintf(2, "usage: sleep time\n");exit(1);}sleep(atoi(argv[1]));exit(0);
}

pingpong

该程序的要求就是创建一个子进程,父进程为子进程发送一个字节,子进程接收到字节之后,打印ping,向父进程发送一个字节,父进程接收到该字节之后打印pong,程序结束。
做法就是打开两个管道,一个用于父进程写子进程读,另一个则相反。

#include "kernel/types.h"
#include "user/user.h"int main(int argc, char* argv[]) 
{if (argc != 1) { fprintf(2, "usage: pingpong\n");exit(1);}int p_father_to_child[2];int p_child_to_father[2];if (pipe(p_father_to_child) == -1 || pipe(p_child_to_father) == -1) {fprintf(2, "failed to open pipe\n");exit(1);}char buf = 'C';int exit_state = 0;// child processif (fork() == 0) {close(p_father_to_child[1]);close(p_child_to_father[0]);if (read(p_father_to_child[0], &buf, 1) != 1) {fprintf(2, "failed to read pipe in child\n");exit_state = 1;}fprintf(1, "%d: received ping\n", getpid());if (write(p_child_to_father[1], &buf, 1) != 1) {fprintf(2, "failed to write pipe in child\n");exit_state = 1;}exit(exit_state);}// father processclose(p_father_to_child[0]);close(p_child_to_father[1]);if (write(p_father_to_child[1], &buf, 1) != 1) {fprintf(2, "failed to write pipe in parent\n");exit_state = 1;}wait(0);if (read(p_child_to_father[0], &buf, 1) != 1) {fprintf(2, "failed to read pipe in parent\n");exit_state = 1;}fprintf(1, "%d: received pong\n", getpid());exit(exit_state);
}

primes

该题目要求我们写一个并发运行的素数筛,其思想大致如下:
建立若干个进程,前一个进程的输出为后一个进程的输入(用管道进行连接);
第一个进程没有输入,向管道直接输出2~35;第二个进程以第一个进程的输出作为输入(2~35),向终端输出2(素数),并筛掉2的倍数,向下一个管道输出非2倍数的数,以此类推,直到没有数输出为止即可。

#include "kernel/types.h"
#include "user/user.h"#define RD 0
#define WR 1
const uint INT_SIZE = sizeof(int);void getprime(int left_p[]) {// check if there has a primeint prime, i;if (read(left_p[RD], &prime, INT_SIZE) == 0) {close(left_p[RD]);exit(0);}fprintf(1, "prime %d\n", prime);// create the pipe to the right neighborint right_p[2];pipe(right_p);// read the data from left neighborwhile (read(left_p[RD], &i, INT_SIZE) != 0) {if (i % prime != 0) write(right_p[WR], &i, INT_SIZE);}close(left_p[RD]);close(right_p[WR]);if (fork() == 0) {getprime(right_p);} else {close(right_p[RD]);wait(0);}}int main(int argc, char* argv[]) 
{if (argc != 1) { fprintf(1, "usage: primes\n");exit(1);}int p[2], i;pipe(p);for (i = 2; i <= 35; i ++ ) {write(p[WR], &i, INT_SIZE);}close(p[WR]);if (fork() == 0) {getprime(p);} else {close(p[RD]);wait(0);}exit(0);
}

find

该题目要求写一个程序,在指定的目录中查找与给定文件名相同的文件,若查找到了则输出文件路径(从指定目录开始的路径)。
根据提示,查看user/ls.c文件中ls程序的实现,其中使用fstat函数查看当前路径的类型(目录或文件)
类似的,我们实现的文件查找也使用fstat函数判断路径类型,如果当前路径是文件,则与给定的文件名比较(相等则输出);如果当前路径是目录,则遍历目录中的内容进行递归查找(注意不要对...递归)

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"void find_file(char* path, const char* filename) {struct dirent de;struct stat st;int fd;char buf[512], *p;if ((fd = open(path, 0)) < 0) {fprintf(2, "find: cannot open %s\n", path);exit(1);}if (fstat(fd, &st) < 0) {fprintf(2, "find: cannot stat %s\n", path);close(fd);exit(1);}if (st.type == T_FILE) {fprintf(2, "usgae: find  \n");close(fd);exit(1);}if (strlen(path) + 1 + DIRSIZ + 1 > sizeof buf) {fprintf(2, "find: path too long\n");close(fd);exit(1);}strcpy(buf, path);p = buf + strlen(buf);*p ++ = '/';while (read(fd, &de, sizeof(de)) == sizeof(de)) {if (de.inum == 0) continue;memmove(p, de.name, DIRSIZ);p[DIRSIZ] = 0;if (stat(buf, &st) < 0) {fprintf(2, "find: cannot stat %s\n", buf);continue;}if (st.type == T_FILE) {if (strcmp(p, filename) == 0) fprintf(1, "%s\n", buf);} else if (st.type == T_DIR && strcmp(p, ".") != 0 && strcmp(p, "..") != 0) {find_file(buf, filename);}}close(fd);
}int main(int argc, char* argv[]) 
{if (argc != 3) {fprintf(2, "usgae: find  \n");exit(1);}find_file(argv[1], argv[2]);exit(0);
}

xargs

该题要求实现一个程序,每从标准输入中读取一行,就调用一次命令(参数是命令)。
这个其实不难(但是我一开始把buf开大了,调了一个小时),大概就是从标准输入读取一行,然后分割成若干个命令行参数,创建一个子进程后使用ecex执行命令即可。

#include "kernel/types.h"
#include "kernel/param.h"
#include "user/user.h"#define LINE 1024int read_line(int fd, char* buf, int len) {char* p = buf;int i = 0;while (i < len - 1) {int res = read(fd, p, 1);if (res == -1) return -1;else if (res == 0)break;p ++;i ++;if (*(p - 1) == '\n') break;}*p = 0;return i;
}int main(int argc, char* argv[])
{if (argc == 1) {fprintf(2, "usage: xargs command [args]\n");exit(1);}char* args[MAXARG + 1];memset(args, 0, sizeof args);int args_num = argc - 1;int i, j, k;for (i = 1; i < argc; i ++ )args[i - 1] = argv[i];        char buf[LINE];int res;while ( (res = read_line(0, buf, LINE)) != 0 ) {if (res == -1) {fprintf(2, "xargs: cannot read line from standard input\n");exit(1);}if (buf[res - 1] != '\n' && res == LINE) {fprintf(2, "xargs: line too long\n");exit(1);}// split the argsbuf[-- res] = '\0';i = 0, k = args_num;while (i < res) {if (buf[i] == ' ') i ++;else {j = i;while (j < res && buf[j] != ' ')j ++;// buf[i ~ j - 1] is an argumentif (k == MAXARG) {fprintf(2, "xargs: too many arguments\n");}args[k] = (char*)malloc(sizeof(char) * (j - i + 1));memcpy(args[k], buf + i, j - i);args[k][j - i + 1] = '\0';k ++;i = j;}}if (fork() == 0) {exec(args[0], args);fprintf(2, "xargs: command %s not found\n", args[0]);}wait(0);// free the malloc spacefor (i = args_num; i < k; i ++ ) free(args[i]), args[i] = 0;}exit(0);
}

相关内容

热门资讯

项少龙的女朋友 项少龙的女朋友展开全部 你好!古天乐饰演的项少龙,他最后没有回到现代,不过影片开头的时候他做梦回...
量子物理学入门书籍 量子物理学入门书籍 你可以先看一下《时间简史(普及版)》它不仅由浅入深而且几乎所有的专业词汇都有...
浪漫的名人格言 浪漫的名人格言名人说的执着之爱,不渝之情,缠绵之思,凄切之苦,永恒之盼。 被爱是一种恩惠,必须全心全...
西班牙历史上最著名的斗牛士是哪... 西班牙历史上最著名的斗牛士是哪位 西班牙最有名的斗牛士是马诺莱特,他取得的巨大成功和他在1947年的...
美国洛杉矶一隧道坍塌 15人被... 来源:央视新闻客户端 美国加利福尼亚州洛杉矶市消防局9日说,该市威尔明顿地区当日发生一起隧道坍塌事故...
三星推全球最轻大折叠,电池容量...   炒股就看金麒麟分析师研报,权威,专业,及时,全面,助您挖掘潜力主题机会! 当地时间7月9日,三...
高德红外涨2.38%,成交额4... 7月10日,高德红外盘中上涨2.38%,截至13:00,报10.33元/股,成交4.01亿元,换手率...
中国古代寓言故事记录其中的三本... 中国古代寓言故事记录其中的三本书是哪三本?作品目录爱钱如命爱驴暗室百发百中扁鹊说病鹬蚌相争杯弓蛇影卞...
中国目的地·入境游简报008|... 本期简报为2025年6月1日至30日中国入境游相关内容:作为正式步入暑期的第一级台阶,6月的入境游市...
航班开始滑行又返回下客,吉祥航...   每经编辑|杜宇   7月10日,吉祥航空官方微博发布关于7月9日HO1860航班情况的说明...