1use alloc::{string::ToString, vec::Vec};
2
3use crate::{arch::Trapframe, task::mytask};
4
5use super::{File, SeekFrom, VfsManager, MAX_PATH_LENGTH};
6
7pub fn sys_open(trapframe: &mut Trapframe) -> usize {
8 let task = mytask().unwrap();
9 let path_ptr = task.vm_manager.translate_vaddr(trapframe.get_arg(0)).unwrap() as *const u8;
10 let _flags = trapframe.get_arg(1) as i32;
11 let _mode = trapframe.get_arg(2) as i32;
12
13 trapframe.epc += 4;
15
16 let mut path_bytes = Vec::new();
18 let mut i = 0;
19 unsafe {
20 loop {
21 let byte = *path_ptr.add(i);
22 if byte == 0 {
23 break;
24 }
25 path_bytes.push(byte);
26 i += 1;
27
28 if i > MAX_PATH_LENGTH {
29 return usize::MAX; }
31 }
32 }
33
34 let path_str = match str::from_utf8(&path_bytes) {
36 Ok(s) => VfsManager::to_absolute_path(&task, s).unwrap(),
37 Err(_) => return usize::MAX, };
39
40 let vfs = match task.vfs.as_ref() {
42 Some(vfs) => vfs,
43 None => return usize::MAX, };
45 let file = vfs.open(&path_str, 0);
46 match file {
47 Ok(file) => {
48 let fd = task.add_file(file);
50 if fd.is_err() {
51 return usize::MAX; }
53 fd.unwrap() as usize
54 }
55 Err(_) => usize::MAX, }
57}
58
59pub fn sys_close(trapframe: &mut Trapframe) -> usize {
60 let task = mytask().unwrap();
61 let fd = trapframe.get_arg(0) as usize;
62 trapframe.epc += 4;
63 if task.remove_file(fd).is_ok() {
64 0
65 } else {
66 usize::MAX }
68}
69
70pub fn sys_read(trapframe: &mut Trapframe) -> usize {
71 let task = mytask().unwrap();
72 let fd = trapframe.get_arg(0) as usize;
73 let buf_ptr = task.vm_manager.translate_vaddr(trapframe.get_arg(1)).unwrap() as *mut u8;
74 let count = trapframe.get_arg(2) as usize;
75
76 trapframe.epc += 4;
78
79 let file = task.get_mut_file(fd);
80 if file.is_none() {
81 return usize::MAX; }
83
84 let file = file.unwrap();
85
86 let buffer = unsafe { core::slice::from_raw_parts_mut(buf_ptr, count) };
87
88 match file.read(buffer) {
89 Ok(n) => {
90 n
91 }
92 Err(_) => {
93 return usize::MAX; }
95 }
96}
97
98pub fn sys_write(trapframe: &mut Trapframe) -> usize {
99 let task = mytask().unwrap();
100 let fd = trapframe.get_arg(0) as usize;
101 let buf_ptr = task.vm_manager.translate_vaddr(trapframe.get_arg(1)).unwrap() as *const u8;
102 let count = trapframe.get_arg(2) as usize;
103
104 trapframe.epc += 4;
106
107 let file = task.get_mut_file(fd);
108 if file.is_none() {
109 return usize::MAX; }
111
112 let file = file.unwrap();
113
114 let buffer = unsafe { core::slice::from_raw_parts(buf_ptr, count) };
115
116 match file.write(buffer) {
117 Ok(n) => {
118 n
119 }
120 Err(_) => {
121 return usize::MAX; }
123 }
124}
125
126pub fn sys_lseek(trapframe: &mut Trapframe) -> usize {
127 let task = mytask().unwrap();
128 let fd = trapframe.get_arg(0) as usize;
129 let offset = trapframe.get_arg(1) as i64;
130 let whence = trapframe.get_arg(2) as i32;
131
132 trapframe.epc += 4;
134
135 let file = task.get_mut_file(fd);
136 if file.is_none() {
137 return usize::MAX; }
139
140 let file = file.unwrap();
141 let whence = match whence {
142 0 => SeekFrom::Start(offset as u64),
143 1 => SeekFrom::Current(offset),
144 2 => SeekFrom::End(offset),
145 _ => return usize::MAX, };
147
148 match file.seek(whence) {
149 Ok(pos) => {
150 pos as usize
151 }
152 Err(_) => {
153 return usize::MAX; }
155 }
156}