From f3735a19c63ef73b19b1fcb36a102e9c59f15dc9 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Sat, 22 Jul 2023 00:40:31 +0300 Subject: [PATCH] alnyan/yggdrasil: directory read implementation --- library/std/src/sys/yggdrasil/alloc.rs | 1 + library/std/src/sys/yggdrasil/fs/dir.rs | 124 ++++++++++++++++++ library/std/src/sys/yggdrasil/fs/mod.rs | 102 ++------------ .../std/src/sys/yggdrasil/thread_local_key.rs | 4 - 4 files changed, 135 insertions(+), 96 deletions(-) create mode 100644 library/std/src/sys/yggdrasil/fs/dir.rs diff --git a/library/std/src/sys/yggdrasil/alloc.rs b/library/std/src/sys/yggdrasil/alloc.rs index b0083c949e4..e2362d88b2c 100644 --- a/library/std/src/sys/yggdrasil/alloc.rs +++ b/library/std/src/sys/yggdrasil/alloc.rs @@ -7,6 +7,7 @@ unsafe impl GlobalAlloc for System { yggdrasil_rt::alloc::malloc(layout) } + #[inline] unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { yggdrasil_rt::alloc::malloc_zeroed(layout) } diff --git a/library/std/src/sys/yggdrasil/fs/dir.rs b/library/std/src/sys/yggdrasil/fs/dir.rs new file mode 100644 index 00000000000..22daa8475d9 --- /dev/null +++ b/library/std/src/sys/yggdrasil/fs/dir.rs @@ -0,0 +1,124 @@ +use yggdrasil_rt::io::DirectoryEntry as OsDirectoryEntry; + +use crate::ffi::OsString; +use crate::fmt; +use crate::io; +use crate::mem::MaybeUninit; +use crate::os::yggdrasil::io::{AsRawFd, FromRawFd}; +use crate::path::{Path, PathBuf}; +use crate::str::FromStr; +use crate::sys::fd::FileDesc; +use crate::sys::yggdrasil::cvt_io; +use crate::sys::yggdrasil::fs::{FileAttr, FileType}; + +pub struct DirEntry { + filename: OsString, + path: PathBuf, + ty: FileType, +} + +pub struct ReadDir { + fd: FileDesc, + path: PathBuf, + buffer: Option, +} + +#[derive(Debug)] +pub struct DirBuilder {} + +impl ReadDir { + fn open(path: &Path) -> io::Result { + let path_buf = PathBuf::from(path); + let path_str = path.to_str().unwrap(); + let fd = cvt_io(unsafe { yggdrasil_rt::sys::open_directory(None, path_str) })?; + Ok(ReadDir { fd: unsafe { FileDesc::from_raw_fd(fd) }, buffer: None, path: path_buf }) + } + + fn fill_buffer(&mut self) -> io::Result<()> { + if self.buffer.is_some() { + return Ok(()); + } + + let mut readbuf = [MaybeUninit::uninit(); 1]; + let count = cvt_io(unsafe { + yggdrasil_rt::sys::read_directory_entries(self.fd.as_raw_fd(), &mut readbuf) + })?; + + assert!(count <= 1); + if count == 1 { + self.buffer.replace(unsafe { readbuf[0].assume_init() }); + } + + Ok(()) + } +} + +impl Iterator for ReadDir { + type Item = io::Result; + + fn next(&mut self) -> Option> { + if let Err(e) = self.fill_buffer() { + return Some(Err(e)); + } + + // buffer should have an entry by now + let entry = self.buffer.take(); + + entry.map(|e| Ok(DirEntry::from_raw(self.path.clone(), &e))) + } +} + +impl fmt::Debug for ReadDir { + fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { + todo!() + } +} + +impl DirEntry { + fn from_raw(parent: PathBuf, raw: &OsDirectoryEntry) -> Self { + // TODO this is ugly + let name_nul = raw.name.iter().position(|&x| x == 0).unwrap(); + let name_str = crate::str::from_utf8(&raw.name[..name_nul]).unwrap(); + let filename = OsString::from_str(name_str).unwrap(); + + Self { path: parent.join(filename.clone()), filename, ty: FileType(raw.ty) } + } + + pub fn path(&self) -> PathBuf { + self.path.clone() + } + + pub fn file_name(&self) -> OsString { + self.filename.clone() + } + + pub fn metadata(&self) -> io::Result { + todo!() + } + + pub fn file_type(&self) -> io::Result { + Ok(self.ty) + } +} + +impl DirBuilder { + pub fn new() -> DirBuilder { + todo!() + } + + pub fn mkdir(&self, _p: &Path) -> io::Result<()> { + todo!() + } +} + +pub fn readdir(path: &Path) -> io::Result { + ReadDir::open(path) +} + +pub fn rmdir(_p: &Path) -> io::Result<()> { + todo!() +} + +pub fn remove_dir_all(_p: &Path) -> io::Result<()> { + todo!() +} diff --git a/library/std/src/sys/yggdrasil/fs/mod.rs b/library/std/src/sys/yggdrasil/fs/mod.rs index 176cd5305e6..5f09c8a3dfa 100644 --- a/library/std/src/sys/yggdrasil/fs/mod.rs +++ b/library/std/src/sys/yggdrasil/fs/mod.rs @@ -1,26 +1,26 @@ -use crate::ffi::OsString; use crate::fmt; -use crate::hash::{Hash, Hasher}; +use crate::hash::Hash; use crate::io; use crate::path::{Path, PathBuf}; use crate::sys::time::SystemTime; +use yggdrasil_rt::io::FileType as OsFileType; + +mod dir; mod file; +pub use dir::{readdir, remove_dir_all, rmdir, DirBuilder, DirEntry, ReadDir}; pub use file::{File, OpenOptions}; pub struct FileAttr(!); pub struct FilePermissions(!); -pub struct FileType(!); + +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub struct FileType(OsFileType); #[derive(Copy, Clone, Debug, Default)] pub struct FileTimes {} -pub struct DirEntry(!); -pub struct ReadDir(!); -#[derive(Debug)] -pub struct DirBuilder {} - impl FileAttr { pub fn size(&self) -> u64 { todo!() @@ -85,11 +85,11 @@ impl fmt::Debug for FilePermissions { impl FileType { pub fn is_dir(&self) -> bool { - todo!() + self.0 == OsFileType::Directory } pub fn is_file(&self) -> bool { - todo!() + self.0 == OsFileType::File } pub fn is_symlink(&self) -> bool { @@ -97,34 +97,6 @@ impl FileType { } } -impl Clone for FileType { - fn clone(&self) -> Self { - todo!() - } -} - -impl Copy for FileType {} - -impl PartialEq for FileType { - fn eq(&self, _other: &Self) -> bool { - todo!() - } -} - -impl Eq for FileType {} - -impl Hash for FileType { - fn hash(&self, _h: &mut H) { - todo!() - } -} - -impl fmt::Debug for FileType { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - todo!() - } -} - impl FileTimes { pub fn set_accessed(&mut self, _t: SystemTime) { todo!() @@ -135,52 +107,6 @@ impl FileTimes { } } -impl Iterator for ReadDir { - type Item = io::Result; - - fn next(&mut self) -> Option> { - todo!() - } -} - -impl fmt::Debug for ReadDir { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - todo!() - } -} - -impl DirEntry { - pub fn path(&self) -> PathBuf { - todo!() - } - - pub fn file_name(&self) -> OsString { - todo!() - } - - pub fn metadata(&self) -> io::Result { - todo!() - } - - pub fn file_type(&self) -> io::Result { - todo!() - } -} - -impl DirBuilder { - pub fn new() -> DirBuilder { - todo!() - } - - pub fn mkdir(&self, _p: &Path) -> io::Result<()> { - todo!() - } -} - -pub fn readdir(_p: &Path) -> io::Result { - todo!() -} - pub fn unlink(_p: &Path) -> io::Result<()> { todo!() } @@ -193,10 +119,6 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> { todo!() } -pub fn remove_dir_all(_p: &Path) -> io::Result<()> { - todo!() -} - pub fn readlink(_p: &Path) -> io::Result { todo!() } @@ -221,10 +143,6 @@ pub fn canonicalize(_p: &Path) -> io::Result { todo!() } -pub fn rmdir(_p: &Path) -> io::Result<()> { - todo!() -} - pub fn copy(_from: &Path, _to: &Path) -> io::Result { todo!() } diff --git a/library/std/src/sys/yggdrasil/thread_local_key.rs b/library/std/src/sys/yggdrasil/thread_local_key.rs index 183a798db17..f234a326565 100644 --- a/library/std/src/sys/yggdrasil/thread_local_key.rs +++ b/library/std/src/sys/yggdrasil/thread_local_key.rs @@ -27,7 +27,6 @@ impl LocalKey { #[inline] pub unsafe fn create(dtor: Option) -> Key { - yggdrasil_rt::sys::debug_trace("thread_local_key::create()"); let boxed = Box::new(LocalKey::new(dtor)); let key = Box::into_raw(boxed); key as usize @@ -35,20 +34,17 @@ pub unsafe fn create(dtor: Option) -> Key { #[inline] pub unsafe fn set(key: Key, value: *mut u8) { - yggdrasil_rt::sys::debug_trace("thread_local_key::set()"); let key = key as *mut LocalKey; (*key).data = value; } #[inline] pub unsafe fn get(key: Key) -> *mut u8 { - yggdrasil_rt::sys::debug_trace("thread_local_key::get()"); let key = key as *mut LocalKey; (*key).data } #[inline] pub unsafe fn destroy(key: Key) { - yggdrasil_rt::sys::debug_trace("thread_local_key::destroy()"); LocalKey::destroy(key as *mut LocalKey) }