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
use crate::process::my_proc;
use crate::syscall::{arg_int, arg_uint, arg_ptr, arg_fd, arg_ptr_mut};
use crate::file::{File, Console, FsFile};
use alloc::sync::Arc;
use crate::spinlock::Mutex;
use crate::symbols::PAGE_SIZE;
use crate::virtio::BSIZE;
pub fn sys_write() -> i32 {
let p = my_proc();
let sz = arg_uint(&p.trapframe, 2);
if sz > BSIZE {
panic!("size > BSIZE not supported");
}
let content = arg_ptr(&p.pgtable, &p.trapframe, 1, sz);
let u8_slice = unsafe { core::slice::from_raw_parts(content, sz) };
let file = arg_fd(&p, 0);
match (*file).as_ref() {
File::Device(dev) => dev.write(u8_slice),
File::FsFile(file) => file.write(u8_slice),
_ => { unimplemented!(); }
}
}
pub fn sys_read() -> i32 {
let p = my_proc();
let sz = arg_uint(&p.trapframe, 2);
if sz > BSIZE {
panic!("size > BSIZE not supported");
}
let content = arg_ptr_mut(&p.pgtable, &p.trapframe, 1, sz);
let u8_slice = unsafe { core::slice::from_raw_parts_mut(content, sz) };
let file = arg_fd(&p, 0);
match (*file).as_ref() {
File::Device(dev) => dev.read(u8_slice),
File::FsFile(file) => file.read(u8_slice),
_ => { unimplemented!(); }
}
}
fn next_available_fd<T>(files: &[Option<T>]) -> Option<usize> {
for i in 0..files.len() {
match files[i] {
None => { return Some(i); }
_ => { continue; }
}
}
return None;
}
pub fn sys_open() -> i32 {
let p = my_proc();
let sz = arg_uint(&p.trapframe, 1);
let mode = arg_uint(&p.trapframe, 2);
let content = arg_ptr(&p.pgtable, &p.trapframe, 0, sz);
let path = core::str::from_utf8(unsafe { core::slice::from_raw_parts(content, sz) }).unwrap();
let fd = match next_available_fd(&p.files) {
Some(fd) => fd,
None => { return -1; }
};
if path == "/console" {
p.files[fd] = Some(Arc::new(File::Device(box Console {})));
} else {
p.files[fd] = Some(Arc::new(File::FsFile(FsFile::open(path, mode))));
}
return fd as i32;
}
pub fn sys_close() -> i32 {
let p = my_proc();
let fd = arg_int(&p.trapframe, 0) as usize;
p.files[fd] = None;
0
}
pub fn sys_dup() -> i32 {
let p = my_proc();
let old_fd = arg_uint(&p.trapframe, 0);
let fd = match next_available_fd(&p.files) {
Some(fd) => fd,
None => { return -1; }
};
p.files[fd] = Some(p.files[old_fd].as_ref().unwrap().clone());
use crate::info;
fd as i32
}