//! File and filesystem-related syscalls use crate::mm::translated_byte_buffer; use crate::mm::translated_str; use crate::mm::translated_refmut; use crate::task::current_user_token; use crate::task::current_task; use crate::fs::open_file; use crate::fs::OpenFlags; use crate::fs::Stat; use crate::fs::make_pipe; use crate::mm::UserBuffer; use alloc::sync::Arc; pub fn sys_write(fd: usize, buf: *const u8, len: usize) -> isize { let token = current_user_token(); let task = current_task().unwrap(); let inner = task.inner_exclusive_access(); if fd >= inner.fd_table.len() { return -1; } if let Some(file) = &inner.fd_table[fd] { let file = file.clone(); // release current task TCB manually to avoid multi-borrow drop(inner); file.write( UserBuffer::new(translated_byte_buffer(token, buf, len)) ) as isize } else { -1 } } pub fn sys_read(fd: usize, buf: *const u8, len: usize) -> isize { let token = current_user_token(); let task = current_task().unwrap(); let inner = task.inner_exclusive_access(); if fd >= inner.fd_table.len() { return -1; } if let Some(file) = &inner.fd_table[fd] { let file = file.clone(); // release current task TCB manually to avoid multi-borrow drop(inner); file.read( UserBuffer::new(translated_byte_buffer(token, buf, len)) ) as isize } else { -1 } } pub fn sys_open(path: *const u8, flags: u32) -> isize { let task = current_task().unwrap(); let token = current_user_token(); let path = translated_str(token, path); if let Some(inode) = open_file( path.as_str(), OpenFlags::from_bits(flags).unwrap() ) { let mut inner = task.inner_exclusive_access(); let fd = inner.alloc_fd(); inner.fd_table[fd] = Some(inode); fd as isize } else { -1 } } pub fn sys_close(fd: usize) -> isize { let task = current_task().unwrap(); let mut inner = task.inner_exclusive_access(); if fd >= inner.fd_table.len() { return -1; } if inner.fd_table[fd].is_none() { return -1; } inner.fd_table[fd].take(); 0 } pub fn sys_pipe(pipe: *mut usize) -> isize { let task = current_task().unwrap(); let token = current_user_token(); let mut inner = task.inner_exclusive_access(); let (pipe_read, pipe_write) = make_pipe(); let read_fd = inner.alloc_fd(); inner.fd_table[read_fd] = Some(pipe_read); let write_fd = inner.alloc_fd(); inner.fd_table[write_fd] = Some(pipe_write); *translated_refmut(token, pipe) = read_fd; *translated_refmut(token, unsafe { pipe.add(1) }) = write_fd; 0 } pub fn sys_dup(fd: usize) -> isize { let task = current_task().unwrap(); let mut inner = task.inner_exclusive_access(); if fd >= inner.fd_table.len() { return -1; } if inner.fd_table[fd].is_none() { return -1; } let new_fd = inner.alloc_fd(); inner.fd_table[new_fd] = Some(Arc::clone(inner.fd_table[fd].as_ref().unwrap())); new_fd as isize } // YOUR JOB: 扩展 easy-fs 和内核以实现以下三个 syscall pub fn sys_fstat(_fd: usize, _st: *mut Stat) -> isize { -1 } pub fn sys_linkat(_old_name: *const u8, _new_name: *const u8) -> isize { -1 } pub fn sys_unlinkat(_name: *const u8) -> isize { -1 }