MIT 6.S081 操作系统课程系列1 Utilities

MIT 6.S081 操作系统课程系列1 Utilities


课程主页:https://pdos.csail.mit.edu/6.828/2020/schedule.html

课程目的

  1. 理解操作系统的设计和实现
  2. 能动手扩展一个小型os
  3. 能动手实现系统应用

这是mit的一套本科课程,希望能快速过一遍,扩展知识,查漏补缺。

RISC-V

xv6

环境安装

实验流程

切换到此次lab的分支git checkout util
本次实验需要实现几个常用的shell命令。
需要参考user文件夹下已实现的命令。

1. sleep

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int
main(int argc, char *argv[])
{

if(argc != 2)
{
fprintf(2, "missing arg\n");
}
else
{

int ticks = atoi(argv[1]);
fprintf(2, "sleep %d ticks\n", ticks);
sleep(ticks);
}

exit(0);
}

2. pingpong

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

int main(int argc, char *argv[])
{
int p_read_pipe[2];
int c_read_pipe[2];
char buf;
char data = 'G';

int pid;

if(pipe(p_read_pipe) == -1){
fprintf(2, "p_read_pipe failed\n");
exit(0);
}

if(pipe(c_read_pipe) == -1){
fprintf(2, "c_read_pipe failed\n");
exit(0);
}

pid = fork();

if(pid == -1){
fprintf(2, "fork failed\n");
exit(0);
}
else if(pid == 0)
{
fprintf(2, "child\n");
read(c_read_pipe[0], &buf, 1);
fprintf(2, "%d: received ping\n", getpid());
write(p_read_pipe[1], &data, 1);

close(p_read_pipe[1]);
close(c_read_pipe[0]);
}
else if(pid > 0)
{
fprintf(2, "parent\n");
write(c_read_pipe[1], &data, 1);
read(p_read_pipe[0], &buf, 1);

close(c_read_pipe[1]);
close(p_read_pipe[0]);
fprintf(2, "%d: received pong\n", getpid());
wait(0);
}

exit(0);
}

3. primes

4. find

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"

char*
fmtname(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));

//if(padding)
// memset(buf+strlen(p), ' ', DIRSIZ-strlen(p));
memset(buf+strlen(p), 0, DIRSIZ-strlen(p));
return buf;
}

void find(char *path, char *name)
{
//printf("find %s %s\n", path, name);
char buf[512], *p;
int fd;
struct dirent de;
struct stat st;

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:
//printf("%s %d %d %l\n", fmtname(path), st.type, st.ino, st.size);
if(strcmp(name, fmtname(path)) == 0)
{
fprintf(1, "%s\n", path);
//printf(0, "%s\n", path);
}
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(de.inum == 0)
continue;
memmove(p, de.name, DIRSIZ);
p[DIRSIZ] = 0;
if(stat(buf, &st) < 0){
printf("ls: cannot stat %s\n", buf);
continue;
}


//printf("gg %s\n", buf);
//printf("gg2 %s %d\n", fmtname(buf), strlen(fmtname(buf)));
if(strcmp("..", fmtname(buf)) != 0 && strcmp(".", fmtname(buf)) != 0)
{
//printf("gg3 %s\n", fmtname(buf));
//printf("%d\n", strcmp(".", fmtname(buf)));
//printf("gg4 %d\n", strlen(fmtname(buf)));
//printf("gg5 %d\n", strlen("."));
find(buf, name);
}
//printf("%s %d %d %d\n", fmtname(buf), st.type, st.ino, st.size);
}
break;
}
close(fd);
}


int
main(int argc, char *argv[])
{
if(argc != 3){
fprintf(2, "error arg\n");
exit(0);
}

find(argv[1], argv[2]);

exit(0);
}

5. xargs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

// sh < xargstest.sh
// find . b | xargs grep hello

int main(int argc, char *argv[])
{

char wtf;

char child_buf[256];
memset(child_buf, 0, sizeof(child_buf));

char *child_argv[4];
child_argv[0] = argv[1];
child_argv[1] = argv[2];
child_argv[2] = child_buf;
child_argv[3] = 0;

while(read(0, &wtf, 1))
{
if(wtf != '\n' && wtf != ' ')
{
memset(child_buf + strlen(child_buf), wtf, 1);
continue;
}

int pid;

pid = fork();

if(pid == -1){
fprintf(2, "fork failed\n");
exit(0);
}
else if(pid == 0) // child
{
//printf("1 %s\n", argv[1]);
//printf("2 %s\n", child_argv[1]);
//printf("3 %s\n", child_argv[2]);
exec(argv[1], child_argv);
}
else if(pid > 0) // parent
{
wait(0);
}

memset(child_buf, 0, sizeof(child_buf));
}

exit(0);
}

上次更新 2021-01-28