diff --git a/src/fd/mod.rs b/src/fd/mod.rs index 5e366d0c1c..a910bb6deb 100644 --- a/src/fd/mod.rs +++ b/src/fd/mod.rs @@ -12,7 +12,7 @@ use smoltcp::wire::{IpEndpoint, IpListenEndpoint}; use crate::arch::kernel::core_local::core_scheduler; use crate::executor::{block_on, poll_on}; -use crate::fs::{self, DirectoryEntry, FileAttr, SeekWhence}; +use crate::fs::{DirectoryEntry, FileAttr, SeekWhence}; mod eventfd; #[cfg(all(any(feature = "tcp", feature = "udp"), not(feature = "newlib")))] @@ -62,7 +62,7 @@ pub(crate) type FileDescriptor = i32; bitflags! { /// Options for opening files #[derive(Debug, Copy, Clone, Default)] - pub(crate) struct OpenOption: i32 { + pub struct OpenOption: i32 { const O_RDONLY = 0o0000; const O_WRONLY = 0o0001; const O_RDWR = 0o0002; @@ -286,26 +286,6 @@ pub(crate) trait ObjectInterface: Sync + Send + core::fmt::Debug + DynClone { } } -pub(crate) fn open( - name: &str, - flags: OpenOption, - mode: AccessPermission, -) -> Result { - // mode is 0x777 (0b0111_0111_0111), when flags | O_CREAT, else 0 - // flags is bitmask of O_DEC_* defined above. - // (taken from rust stdlib/sys hermit target ) - - debug!("Open {}, {:?}, {:?}", name, flags, mode); - - let fs = fs::FILESYSTEM.get().unwrap(); - if let Ok(file) = fs.open(name, flags, mode) { - let fd = insert_object(file)?; - Ok(fd) - } else { - Err(IoError::EINVAL) - } -} - pub(crate) fn read(fd: FileDescriptor, buf: &mut [u8]) -> Result { let obj = get_object(fd)?; diff --git a/src/fs/mod.rs b/src/fs/mod.rs index 16d59c064e..e8c7de0566 100644 --- a/src/fs/mod.rs +++ b/src/fs/mod.rs @@ -18,7 +18,7 @@ use crate::fd::{ use crate::io::Write; use crate::time::{timespec, SystemTime}; -pub(crate) static FILESYSTEM: OnceCell = OnceCell::new(); +static FILESYSTEM: OnceCell = OnceCell::new(); #[derive(Debug, Clone)] pub struct DirectoryEntry { @@ -370,6 +370,15 @@ pub unsafe fn create_file( } } +/// Removes an empty directory. +pub fn remove_dir(path: &str) -> Result<(), IoError> { + FILESYSTEM.get().unwrap().rmdir(path) +} + +pub fn unlink(path: &str) -> Result<(), IoError> { + FILESYSTEM.get().unwrap().unlink(path) +} + /// Creates a new, empty directory at the provided path pub fn create_dir(path: &str, mode: AccessPermission) -> Result<(), IoError> { FILESYSTEM.get().unwrap().mkdir(path, mode) @@ -382,6 +391,34 @@ pub fn readdir(name: &str) -> Result, IoError> { FILESYSTEM.get().ok_or(IoError::EINVAL)?.readdir(name) } +pub fn read_stat(name: &str) -> Result { + FILESYSTEM.get().unwrap().stat(name) +} + +pub fn read_lstat(name: &str) -> Result { + FILESYSTEM.get().unwrap().lstat(name) +} + +pub fn open( + name: &str, + flags: OpenOption, + mode: AccessPermission, +) -> Result { + // mode is 0x777 (0b0111_0111_0111), when flags | O_CREAT, else 0 + // flags is bitmask of O_DEC_* defined above. + // (taken from rust stdlib/sys hermit target ) + + debug!("Open {}, {:?}, {:?}", name, flags, mode); + + let fs = FILESYSTEM.get().unwrap(); + if let Ok(file) = fs.open(name, flags, mode) { + let fd = insert_object(file)?; + Ok(fd) + } else { + Err(IoError::EINVAL) + } +} + /// Open a directory to read the directory entries pub(crate) fn opendir(name: &str) -> Result { let obj = FILESYSTEM.get().unwrap().opendir(name)?; @@ -443,7 +480,7 @@ impl File { /// an error if it does. This way, if the call succeeds, the file /// returned is guaranteed to be new. pub fn create(path: &str) -> Result { - let fd = fd::open( + let fd = open( path, OpenOption::O_CREAT | OpenOption::O_RDWR, AccessPermission::from_bits(0o666).unwrap(), @@ -457,7 +494,7 @@ impl File { /// Attempts to open a file in read-write mode. pub fn open(path: &str) -> Result { - let fd = fd::open( + let fd = open( path, OpenOption::O_RDWR, AccessPermission::from_bits(0o666).unwrap(), diff --git a/src/syscalls/mod.rs b/src/syscalls/mod.rs index 88d429ffa4..0ffc0e7494 100644 --- a/src/syscalls/mod.rs +++ b/src/syscalls/mod.rs @@ -300,11 +300,7 @@ pub(crate) fn shutdown(arg: i32) -> ! { pub unsafe extern "C" fn sys_unlink(name: *const u8) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); - fs::FILESYSTEM - .get() - .unwrap() - .unlink(name) - .map_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap(), |_| 0) + fs::unlink(name).map_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap(), |_| 0) } #[hermit_macro::system] @@ -325,11 +321,7 @@ pub unsafe extern "C" fn sys_mkdir(name: *const u8, mode: u32) -> i32 { pub unsafe extern "C" fn sys_rmdir(name: *const c_char) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); - fs::FILESYSTEM - .get() - .unwrap() - .rmdir(name) - .map_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap(), |_| 0) + crate::fs::remove_dir(name).map_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap(), |_| 0) } #[hermit_macro::system] @@ -337,7 +329,7 @@ pub unsafe extern "C" fn sys_rmdir(name: *const c_char) -> i32 { pub unsafe extern "C" fn sys_stat(name: *const c_char, stat: *mut FileAttr) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); - match fs::FILESYSTEM.get().unwrap().stat(name) { + match fs::read_stat(name) { Ok(attr) => unsafe { *stat = attr; 0 @@ -351,7 +343,7 @@ pub unsafe extern "C" fn sys_stat(name: *const c_char, stat: *mut FileAttr) -> i pub unsafe extern "C" fn sys_lstat(name: *const c_char, stat: *mut FileAttr) -> i32 { let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap(); - match fs::FILESYSTEM.get().unwrap().lstat(name) { + match fs::read_lstat(name) { Ok(attr) => unsafe { *stat = attr; 0 @@ -399,7 +391,7 @@ pub unsafe extern "C" fn sys_open(name: *const c_char, flags: i32, mode: u32) -> }; if let Ok(name) = unsafe { CStr::from_ptr(name as _) }.to_str() { - crate::fd::open(name, flags, mode) + crate::fs::open(name, flags, mode) .unwrap_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap()) } else { -crate::errno::EINVAL