MIT6.S081 Lab1
写在开头
6.S081/2021/Fall
当刚开始做这个实验的时候,我好像又陷入了一个误区,在实现Sleep的时候,我想了解Sleep到底是怎么完成运行的,浪费了一些时间,也没搞懂。
浪费了一段时间之后,我突然意识到:我并不熟悉MakeFile。
不熟悉MakeFile,我不可能去理解这个xv6是怎么运行的。
并且我的目的是去完成这个课程,并不是去了解xv6的运行过程。
如果我完成了这个课程,有了一个系统性的认识之后,到时候我再去了解这些问题。
可能以我现在的能力解决不了这个问题,并且会大大降低我做Lab的积极性。
不如一步一步的把Lab搞好,最后完成所有Lab之后再去研究(或者中途有些Lab会了解到这些知识)
总而言之就是一句话:先把既定的目标做好,做好目标之后会提高积极性,进入良性循环。难题之后再解决,避免降低积极性,陷入恶性循环。
希望自己今年能把这个Lab做完,不要不要半途而废。
Lab1 的主要工作是实现五个工具:Sleep、PingPong、Primes、Find、Xargs
Lab1
Sleep
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int main(int argc, char *args[])
{
if (argc <= 1)
{
fprintf(2, "you need to give sleep time!\n");
exit(1);
}
sleep(atoi(args[1]));
exit(0);
}
PingPong
开始以为xv6的printf只能传char * 不能传%d 这种,所以写的有些臃肿了
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#define PIPE_WRITE 1
#define PIPE_READ 0
#define EOF 0
#define WAIT (int *)0
#define CHILD 0
int main(int argv, char *args[])
{
int p[2];
pipe(p);
int pid = fork();
char *buf[10];
if (pid == CHILD)
{
int child = getpid();
int n = read(p[PIPE_READ], buf, sizeof buf);
char arr[10];
int now = 0;
while (child)
{
arr[now] = '0' + child % 10;
child /= 10;
}
printf(arr);
printf(": received ping\n");
write(p[PIPE_WRITE], buf, n);
close(p[PIPE_READ]);
close(p[PIPE_WRITE]);
exit(0);
}
else
{
pid = getpid();
write(p[PIPE_WRITE], "A", 1);
int status;
wait(&status);
read(p[PIPE_READ], buf, sizeof buf);
char arr[10];
int now = 0;
while (pid)
{
arr[now] = '0' + pid % 10;
pid /= 10;
}
printf(arr);
printf(": received pong\n");
close(p[PIPE_READ]);
close(p[PIPE_WRITE]);
}
exit(0);
}
Primes
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#define PIPE_WRITE 1
#define PIPE_READ 0
#define EOF 0
#define WAIT (int *)0
#define CHILD 0
void primes(int fd[2])
{
int prime;
close(fd[PIPE_WRITE]);
if (read(fd[PIPE_READ], &prime, sizeof(int)) == EOF)
{
return ;
// exit(0); if use 'exit' to exit function
// will throw a error.the error is 'error: infinite recursion detected'
}
// printf("primes %d ", getpid());
printf("prime %d\n", prime);
int pp[2];
pipe(pp);
int ProcessId = fork();
if (ProcessId == CHILD)
{
primes(pp);
exit(0);
}
else
{
int now;
close(pp[PIPE_READ]);
while (read(fd[PIPE_READ], &now, sizeof(int)) != EOF)
{
int cur = now;
if (cur % prime != 0)
write(pp[PIPE_WRITE], &cur, sizeof(int));
}
close(pp[PIPE_WRITE]);
close(fd[PIPE_READ]);
wait(WAIT);
exit(0);
}
}
int main()
{
int fd[2];
pipe(fd);
int pid = fork();
if (pid == CHILD)
{
primes(fd);
exit(0);
}
for (int i = 2; i <= 35; i++)
{
write(fd[PIPE_WRITE], &i, sizeof(int));
}
close(fd[PIPE_READ]);
close(fd[PIPE_WRITE]);
wait(WAIT);
exit(0);
}
primes2
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#define PIPE_WRITE 1
#define PIPE_READ 0
#define EOF 0
#define WAIT (int *)0
void grepPrime(int fd)
{
int p[2];
pipe(p);
int prime;
if (read(fd, &prime, sizeof(int)) == EOF)
{
return;
}
printf("prime %d\n", prime);
int pid = fork();
if (pid == 0)
{
close(fd);
close(p[PIPE_WRITE]);
grepPrime(p[PIPE_READ]);
close(p[PIPE_READ]);
}
else
{
close(p[PIPE_READ]);
int now;
while (read(fd, &now, sizeof(int)) != EOF)
{
if (now % prime != 0)
{
write(p[PIPE_WRITE], &now, sizeof(int));
}
}
close(fd);
close(p[PIPE_WRITE]);
wait(WAIT);
}
}
int main()
{
int fd[2];
pipe(fd);
int pid = fork();
if (pid == 0)
{
close(fd[PIPE_WRITE]);
grepPrime(fd[PIPE_READ]);
}
else
{
close(fd[PIPE_READ]);
for (int i = 2; i <= 35; i++)
{
write(fd[PIPE_WRITE], &i, sizeof(int));
}
close(fd[PIPE_WRITE]);
wait(WAIT);
}
exit(0);
}
Find
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
char *fmt(char *path)
{
static char buf[DIRSIZ + 1];
char *p;
// Find first character after last slash.
for (p = path + strlen(path); p >= path && *p != '/'; p--)
;
p++;
// Return blank-padded name.
if (strlen(p) >= DIRSIZ)
return p;
memmove(buf, p, strlen(p));
buf[strlen(p)] = 0; // end of file name
return buf;
}
void find(char *path, char *pattern)
{
int fd;
struct stat st;
struct dirent de;
char buf[512], *p;
// char *fmtname = fmt(path); // current dir/file name (exclude parents)
if ((fd = open(path, 0)) < 0)
{
fprintf(2, "ls: cannot open %s\n", path);
return;
}
if (fstat(fd, &st) < 0)
{
fprintf(2, "ls: cannot stat %s\n", path);
close(fd);
return;
}
switch (st.type)
{
case T_FILE:
char *file = fmt(path);
if (strcmp(file, pattern) == 0)
{
printf("%s\n", path);
}
close(fd);
break;
case T_DIR:
if (strlen(path) + 1 + DIRSIZ + 1 > sizeof buf)
{
printf("ls: path too long\n");
break;
}
strcpy(buf, path);
p = buf + strlen(buf);
*p++ = '/';
while (read(fd, &de, sizeof(de)) == sizeof(de))
{
if (strcmp(de.name, ".") == 0 || strcmp(de.name, "..") == 0)
continue;
if (de.inum == 0)
continue;
memmove(p, de.name, DIRSIZ);
p[DIRSIZ] = 0;
find(buf, pattern);
}
close(fd);
break;
}
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
fprintf(2, "error , amount of arguments is error");
}
find(argv[1], argv[2]);
exit(0);
}
Xargs
最开始没有想到怎么读入数据,是看到别人的answer之后才想到使用while(read(1))
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
#define READ 0
#define WRITE 1
#define MAXARG 32
int main(int argv, char *args[])
{
char *argument[MAXARG];
int index = 0;
for (int i = 1; i < argv; i++)
{
argument[index++] = args[i];
}
char buf[512];
char *p = buf;
// test "echo 1\n2 | xarg echo line"
// int fd[2];
// pipe(fd);
// char *test = "1\n2";
// write(fd[WRITE], test, sizeof test);
// close(fd[WRITE]);
while (read(READ, p, 1) == 1)
{
if ((*p) != '\n')
{
p++;
}
else
{
*p = 0;
argument[index] = buf;
int pid = fork();
if (pid == 0)
{
exec(argument[0], argument);
fprintf(2, "error");
exit(1);
}
wait(0);
p = buf;
}
}
if (p != buf)
{
*p = 0;
argument[index] = buf;
int pid = fork();
if (pid == 0)
{
exec(argument[0], argument);
fprintf(2, "error");
exit(1);
}
wait(0);
}
exit(0);
}


浙公网安备 33010602011771号