【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);
}

相关内容

热门资讯

开晨会需要说什么内容 开晨会需要说什么内容晨会说的内容可以很多呀,可以说接下来的工作安排,也可以说,前期工作中的一些总结,...
有谁知道在鬼吹灯有声小说中前面... 有谁知道在鬼吹灯有声小说中前面有一段小女孩的声音念:人点烛 鬼吹灯... 这个版本的故事是谁讲的?周...
小蒂皮出自哪本书 小蒂皮出自哪本书小蒂皮出自哪本书我的野生动物朋友(蒂皮·本杰明·奥康迪·德格雷著图书)《我的野生动物...
盘古开天辟地的故事 盘古开天辟地的故事很久很久以前,天和地还没有分开,宇宙混沌一片。有个叫盘古的巨人一直睡在这混沌之中。...
英雄联盟中 赏金猎人怎么样? ... 英雄联盟中 赏金猎人怎么样? 多少钱 金币3150的ADC。入手的话不会吃亏,基本不会压箱底,很热门...
寻找一部累死何以笙箫默之类的小... 寻找一部累死何以笙箫默之类的小说也是辛夷坞的,叫山月不知心底事那就它的作者顾漫的其他小说呗 微微一...
大家谈谈对洪荒小说之中圣人的看... 大家谈谈对洪荒小说之中圣人的看法圣人不死,大盗不止都是人 人有的情绪他们都有 就是拳头大些对...
单位体检,自己一个人去害怕撞到... 单位体检,自己一个人去害怕撞到同事怎么办,不想别人看到观察我,漏出我不成熟样子,显出我的丑态。这让单...
鱼在天上飞? 鱼在天上飞?“鱼在天上飞,鸟在水里游”这句话的意思是鸟儿在水中的倒影就像是在水里游,天空在水中的倒影...
我想复婚,前夫说以后再,我改变... 我想复婚,前夫说以后再,我改变好了,他有可能追我,现在不想复婚,他有喜欢的女人了,我们就不可能了吗感...
原神草神什么时候复刻 原神草神什么时候复刻原神草神复刻是在3.6版本以后。草神纳西妲首次登场是逗腊3.2版本,新角色想要等...
网络拽姐语录小学生? 网络拽姐语录小学生?无论谁离开了你,请你别忘了,他没来之前,你本就是一个人生活。
有一部小说,女主小时候被男主收... 有一部小说,女主小时候被男主收养了,女主叫男主哥哥,男主对女主的我也在找这个小说我之前也看了,好像叫...
高层建筑立面大面积粉刷需要设伸... 高层建筑立面大面积粉刷需要设伸缩缝吗?高层建筑立面大面积粉刷需要设伸缩缝需要的,无正举论地面或立念清...
低头思故乡,为什么把杯思在长,... 低头思故乡,为什么把杯思在长,情愿何处在方歌曲叫什么名字“李白的歌”离开了家乡 背着沉沉的行囊开始了...
李白的诗有多少 李白的诗有多少典故中大多说是三千至四千首,现存不足一千首很多,总之不少~李白一生留下了九百六十多首诗...
怎么才可以学会拿得起放得下……... 怎么才可以学会拿得起放得下…… 有一段感情,正整3年了,可是我还是觉得分手那天就好像昨天发生的一样替...
为什么官方直播间买手机送耳机 为什么官方直播间买手机送耳机吸引消费者,增加销售量。官方直播间作为官方的直播平台,买手机送耳机是为了...
自考通还是一考通好?该选哪个? 自考通还是一考通好?该选哪个?我现在自考行政管理专科。专业课程我应该选自考通好还是一考通好呢?这个很...
淘宝实际付款价格为什么与订单价... 淘宝实际付款价格为什么与订单价格不符是这样的,我买了一双鞋,当时限价160我拍了下来,当时没付款,后...