1use crate::fs::{OpenFlags, make_pipe, open_file};
2use crate::mm::{UserBuffer, translated_byte_buffer, translated_refmut, translated_str};
3use crate::task::{current_process, current_user_token};
4use alloc::sync::Arc;
5
6pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
7 let token = current_user_token();
8 let process = current_process();
9 let inner = process.inner_exclusive_access();
10 if fd >= inner.fd_table.len() {
11 return -1;
12 }
13 if let Some(file) = &inner.fd_table[fd] {
14 if !file.writable() {
15 return -1;
16 }
17 let file = file.clone();
18 drop(inner);
20 file.write(UserBuffer::new(translated_byte_buffer(token, buf, len))) as isize
21 } else {
22 -1
23 }
24}
25
26pub fn sys_read(fd: usize, buf: *const u8, len: usize) -> isize {
27 let token = current_user_token();
28 let process = current_process();
29 let inner = process.inner_exclusive_access();
30 if fd >= inner.fd_table.len() {
31 return -1;
32 }
33 if let Some(file) = &inner.fd_table[fd] {
34 let file = file.clone();
35 if !file.readable() {
36 return -1;
37 }
38 drop(inner);
40 file.read(UserBuffer::new(translated_byte_buffer(token, buf, len))) as isize
41 } else {
42 -1
43 }
44}
45
46pub fn sys_open(path: *const u8, flags: u32) -> isize {
47 let process = current_process();
48 let token = current_user_token();
49 let path = translated_str(token, path);
50 if let Some(inode) = open_file(path.as_str(), OpenFlags::from_bits(flags).unwrap()) {
51 let mut inner = process.inner_exclusive_access();
52 let fd = inner.alloc_fd();
53 inner.fd_table[fd] = Some(inode);
54 fd as isize
55 } else {
56 -1
57 }
58}
59
60pub fn sys_close(fd: usize) -> isize {
61 let process = current_process();
62 let mut inner = process.inner_exclusive_access();
63 if fd >= inner.fd_table.len() {
64 return -1;
65 }
66 if inner.fd_table[fd].is_none() {
67 return -1;
68 }
69 inner.fd_table[fd].take();
70 0
71}
72
73pub fn sys_pipe(pipe: *mut usize) -> isize {
74 let process = current_process();
75 let token = current_user_token();
76 let mut inner = process.inner_exclusive_access();
77 let (pipe_read, pipe_write) = make_pipe();
78 let read_fd = inner.alloc_fd();
79 inner.fd_table[read_fd] = Some(pipe_read);
80 let write_fd = inner.alloc_fd();
81 inner.fd_table[write_fd] = Some(pipe_write);
82 *translated_refmut(token, pipe) = read_fd;
83 *translated_refmut(token, unsafe { pipe.add(1) }) = write_fd;
84 0
85}
86
87pub fn sys_dup(fd: usize) -> isize {
88 let process = current_process();
89 let mut inner = process.inner_exclusive_access();
90 if fd >= inner.fd_table.len() {
91 return -1;
92 }
93 if inner.fd_table[fd].is_none() {
94 return -1;
95 }
96 let new_fd = inner.alloc_fd();
97 inner.fd_table[new_fd] = Some(Arc::clone(inner.fd_table[fd].as_ref().unwrap()));
98 new_fd as isize
99}