Skip to main content

os/syscall/
fs.rs

1//! File and filesystem-related syscalls
2use crate::fs::{OpenFlags, open_file};
3use crate::mm::{UserBuffer, translated_byte_buffer, translated_str};
4use crate::task::{current_task, current_user_token};
5
6pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize {
7    let token = current_user_token();
8    let task = current_task().unwrap();
9    let inner = task.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        // release current task TCB manually to avoid multi-borrow
19        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 task = current_task().unwrap();
29    let inner = task.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        // release current task TCB manually to avoid multi-borrow
39        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 task = current_task().unwrap();
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 = task.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 task = current_task().unwrap();
62    let mut inner = task.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}