Skip to content

Commit 72be8e4

Browse files
committed
Chapter 7
1 parent f36f35a commit 72be8e4

File tree

6 files changed

+176
-50
lines changed

6 files changed

+176
-50
lines changed

.github/workflows/github-autotest.yml

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,16 @@
11
name: auto-test
22

3-
on:
3+
on:
44
push:
55

66
jobs:
77
base-test:
88
runs-on: ubuntu-latest
9-
outputs:
10-
points: ${{ steps.end.outputs.points}}
119
container:
1210
image: duskmoon/dev-env:ucore-ci
1311
steps:
1412
- uses: actions/checkout@v3
15-
- run: git clone https://github.com/LearningOS/uCore-Tutorial-Checker-2023S.git ucore-tutorial-ci
13+
- run: git clone https://github.com/LearningOS/uCore-Tutorial-Checker-2023S.git ucore-tutorial-ci
1614
- run: git clone https://github.com/LearningOS/uCore-Tutorial-Test-2023S.git ucore-tutorial-ci/workplace/user
17-
- name: run test
18-
id: tester
19-
run: cd ucore-tutorial-ci && make test passwd=${{ secrets.BASE_TEST_TOKEN }} CHAPTER=`echo ${GITHUB_REF##*/} | grep -oP 'ch\K[0-9]'` > ../output.txt && cat ../output.txt
20-
- name: end
21-
id: end
22-
run: cat output.txt | grep "Test passed" | grep -oP "\d{1,}/\d{1,}" | xargs -i echo "points={}" >> $GITHUB_OUTPUT
23-
deploy:
24-
if: github.repository != 'LearningOS/uCore-Tutorial-Code-2023S'
25-
name: Deploy to pages
26-
needs: base-test
27-
runs-on: ubuntu-latest
28-
steps:
29-
- uses: actions/checkout@v3
30-
continue-on-error: true
31-
with:
32-
ref: 'gh-pages'
33-
- name: Save Log File
34-
uses: yfblock/multi-rank-log@main
35-
with:
36-
points: ${{ needs.base-test.outputs.points }}
37-
- name: GitHub Pages
38-
uses: crazy-max/ghaction-github-pages@v3
39-
with:
40-
target_branch: gh-pages
41-
build_dir: ./public
42-
keep_history: true
43-
env:
44-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
15+
- run: cd ucore-tutorial-ci && make test passwd=${{ secrets.BASE_TEST_TOKEN }} CHAPTER=`echo ${GITHUB_REF##*/} | grep -oP 'ch\K[0-9]'`
16+

os/file.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ void fileclose(struct file *f)
3030
case FD_STDIO:
3131
// Do nothing
3232
break;
33+
case FD_PIPE:
34+
pipeclose(f->pipe, f->writable);
35+
break;
3336
case FD_INODE:
3437
iput(f->ip);
3538
break;
@@ -63,7 +66,9 @@ int show_all_files()
6366
}
6467

6568
//Create a new empty file based on path and type and return its inode;
69+
6670
//if the file under the path exists, return its inode;
71+
6772
//returns 0 if the type of file to be created is not T_file
6873
static struct inode *create(char *path, short type)
6974
{
@@ -94,7 +99,9 @@ static struct inode *create(char *path, short type)
9499
}
95100

96101
//A process creates or opens a file according to its path, returning the file descriptor of the created or opened file.
102+
97103
//If omode is O_CREATE, create a new file
104+
98105
//if omode if the others,open a created file.
99106
int fileopen(char *path, uint64 omode)
100107
{
@@ -114,10 +121,7 @@ int fileopen(char *path, uint64 omode)
114121
}
115122
if (ip->type != T_FILE)
116123
panic("unsupported file inode type\n");
117-
if ((f = filealloc()) == 0 ||
118-
(fd = fdalloc(f)) <
119-
0) { //Assign a system-level table entry to a newly created or opened file
120-
//and then create a file descriptor that points to it
124+
if ((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0) {
121125
if (f)
122126
fileclose(f);
123127
iput(ip);

os/file.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,23 @@ struct inode {
2020
// LAB4: You may need to add link count here
2121
};
2222

23+
//a struct for pipe
24+
struct pipe {
25+
char data[PIPESIZE];
26+
uint nread; // number of bytes read
27+
uint nwrite; // number of bytes written
28+
int readopen; // read fd is still open
29+
int writeopen; // write fd is still open
30+
};
31+
32+
// file.h
2333
// Defines a file in memory that provides information about the current use of the file and the corresponding inode location
2434
struct file {
25-
enum { FD_NONE = 0, FD_INODE, FD_STDIO } type;
35+
enum { FD_NONE = 0, FD_PIPE, FD_INODE, FD_STDIO } type;
2636
int ref; // reference count
2737
char readable;
2838
char writable;
39+
struct pipe *pipe; // FD_PIPE
2940
struct inode *ip; // FD_INODE
3041
uint off;
3142
};
@@ -39,6 +50,10 @@ enum {
3950

4051
extern struct file filepool[FILEPOOLSIZE];
4152

53+
int pipealloc(struct file *, struct file *);
54+
void pipeclose(struct pipe *, int);
55+
int piperead(struct pipe *, uint64, int);
56+
int pipewrite(struct pipe *, uint64, int);
4257
void fileclose(struct file *);
4358
struct file *filealloc();
4459
int fileopen(char *, uint64);

os/fs.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,8 +428,6 @@ int dirlink(struct inode *dp, char *name, uint inum)
428428
return 0;
429429
}
430430

431-
// LAB4: You may want to add dirunlink here
432-
433431
//Return the inode of the root directory
434432
struct inode *root_dir()
435433
{

os/pipe.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include "defs.h"
2+
#include "proc.h"
3+
#include "riscv.h"
4+
5+
int pipealloc(struct file *f0, struct file *f1)
6+
{
7+
struct pipe *pi;
8+
pi = 0;
9+
if ((pi = (struct pipe *)kalloc()) == 0)
10+
goto bad;
11+
pi->readopen = 1;
12+
pi->writeopen = 1;
13+
pi->nwrite = 0;
14+
pi->nread = 0;
15+
f0->type = FD_PIPE;
16+
f0->readable = 1;
17+
f0->writable = 0;
18+
f0->pipe = pi;
19+
f1->type = FD_PIPE;
20+
f1->readable = 0;
21+
f1->writable = 1;
22+
f1->pipe = pi;
23+
return 0;
24+
bad:
25+
if (pi)
26+
kfree((char *)pi);
27+
return -1;
28+
}
29+
30+
void pipeclose(struct pipe *pi, int writable)
31+
{
32+
if (writable) {
33+
pi->writeopen = 0;
34+
} else {
35+
pi->readopen = 0;
36+
}
37+
if (pi->readopen == 0 && pi->writeopen == 0) {
38+
kfree((char *)pi);
39+
}
40+
}
41+
42+
int pipewrite(struct pipe *pi, uint64 addr, int n)
43+
{
44+
int w = 0;
45+
uint64 size;
46+
struct proc *p = curr_proc();
47+
if (n <= 0) {
48+
panic("invalid read num");
49+
}
50+
while (w < n) {
51+
if (pi->readopen == 0) {
52+
return -1;
53+
}
54+
if (pi->nwrite == pi->nread + PIPESIZE) { // DOC: pipewrite-full
55+
yield();
56+
} else {
57+
size = MIN(MIN(n - w,
58+
pi->nread + PIPESIZE - pi->nwrite),
59+
PIPESIZE - (pi->nwrite % PIPESIZE));
60+
if (copyin(p->pagetable,
61+
&pi->data[pi->nwrite % PIPESIZE], addr + w,
62+
size) < 0) {
63+
panic("copyin");
64+
}
65+
pi->nwrite += size;
66+
w += size;
67+
}
68+
}
69+
return w;
70+
}
71+
72+
int piperead(struct pipe *pi, uint64 addr, int n)
73+
{
74+
int r = 0;
75+
uint64 size = -1;
76+
struct proc *p = curr_proc();
77+
if (n <= 0) {
78+
panic("invalid read num");
79+
}
80+
while (pi->nread == pi->nwrite) {
81+
if (pi->writeopen)
82+
yield();
83+
else
84+
return -1;
85+
}
86+
while (r < n && size != 0) { // DOC: piperead-copy
87+
if (pi->nread == pi->nwrite)
88+
break;
89+
size = MIN(MIN(n - r, pi->nwrite - pi->nread),
90+
PIPESIZE - (pi->nread % PIPESIZE));
91+
if (copyout(p->pagetable, addr + r,
92+
&pi->data[pi->nread % PIPESIZE], size) < 0) {
93+
panic("copyout");
94+
}
95+
pi->nread += size;
96+
r += size;
97+
}
98+
return r;
99+
}

os/syscall.c

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ uint64 sys_write(int fd, uint64 va, uint64 len)
4444
switch (f->type) {
4545
case FD_STDIO:
4646
return console_write(va, len);
47+
case FD_PIPE:
48+
return pipewrite(f->pipe, va, len);
4749
case FD_INODE:
4850
return inodewrite(f, va, len);
4951
default:
@@ -64,6 +66,8 @@ uint64 sys_read(int fd, uint64 va, uint64 len)
6466
switch (f->type) {
6567
case FD_STDIO:
6668
return console_read(va, len);
69+
case FD_PIPE:
70+
return piperead(f->pipe, va, len);
6771
case FD_INODE:
6872
return inoderead(f, va, len);
6973
default:
@@ -154,6 +158,38 @@ uint64 sys_set_priority(long long prio)
154158
return -1;
155159
}
156160

161+
uint64 sys_pipe(uint64 fdarray)
162+
{
163+
struct proc *p = curr_proc();
164+
uint64 fd0, fd1;
165+
struct file *f0, *f1;
166+
if (f0 < 0 || f1 < 0) {
167+
return -1;
168+
}
169+
f0 = filealloc();
170+
f1 = filealloc();
171+
if (pipealloc(f0, f1) < 0)
172+
goto err0;
173+
fd0 = fdalloc(f0);
174+
fd1 = fdalloc(f1);
175+
if (fd0 < 0 || fd1 < 0)
176+
goto err0;
177+
if (copyout(p->pagetable, fdarray, (char *)&fd0, sizeof(fd0)) < 0 ||
178+
copyout(p->pagetable, fdarray + sizeof(uint64), (char *)&fd1,
179+
sizeof(fd1)) < 0) {
180+
goto err1;
181+
}
182+
return 0;
183+
184+
err1:
185+
p->files[fd0] = 0;
186+
p->files[fd1] = 0;
187+
err0:
188+
fileclose(f0);
189+
fileclose(f1);
190+
return -1;
191+
}
192+
157193
uint64 sys_openat(uint64 va, uint64 omode, uint64 _flags)
158194
{
159195
struct proc *p = curr_proc();
@@ -177,6 +213,16 @@ uint64 sys_close(int fd)
177213
return 0;
178214
}
179215

216+
uint64 sys_sbrk(int n)
217+
{
218+
uint64 addr;
219+
struct proc *p = curr_proc();
220+
addr = p->program_brk;
221+
if (growproc(n) < 0)
222+
return -1;
223+
return addr;
224+
}
225+
180226
int sys_fstat(int fd, uint64 stat)
181227
{
182228
//TODO: your job is to complete the syscall
@@ -196,16 +242,6 @@ int sys_unlinkat(int dirfd, uint64 name, uint64 flags)
196242
return -1;
197243
}
198244

199-
uint64 sys_sbrk(int n)
200-
{
201-
uint64 addr;
202-
struct proc *p = curr_proc();
203-
addr = p->program_brk;
204-
if (growproc(n) < 0)
205-
return -1;
206-
return addr;
207-
}
208-
209245
extern char trap_page[];
210246

211247
void syscall()
@@ -253,6 +289,9 @@ void syscall()
253289
case SYS_wait4:
254290
ret = sys_wait(args[0], args[1]);
255291
break;
292+
case SYS_pipe2:
293+
ret = sys_pipe(args[0]);
294+
break;
256295
case SYS_fstat:
257296
ret = sys_fstat(args[0], args[1]);
258297
break;
@@ -261,7 +300,6 @@ void syscall()
261300
break;
262301
case SYS_unlinkat:
263302
ret = sys_unlinkat(args[0], args[1], args[2]);
264-
break;
265303
case SYS_spawn:
266304
ret = sys_spawn(args[0]);
267305
break;

0 commit comments

Comments
 (0)