alnyan/yggdrasil: directory read implementation

This commit is contained in:
2023-07-22 00:40:31 +03:00
parent d5da273762
commit f3735a19c6
4 changed files with 135 additions and 96 deletions
+1
View File
@@ -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)
}
+124
View File
@@ -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<OsDirectoryEntry>,
}
#[derive(Debug)]
pub struct DirBuilder {}
impl ReadDir {
fn open(path: &Path) -> io::Result<Self> {
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<DirEntry>;
fn next(&mut self) -> Option<io::Result<DirEntry>> {
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<FileAttr> {
todo!()
}
pub fn file_type(&self) -> io::Result<FileType> {
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> {
ReadDir::open(path)
}
pub fn rmdir(_p: &Path) -> io::Result<()> {
todo!()
}
pub fn remove_dir_all(_p: &Path) -> io::Result<()> {
todo!()
}
+10 -92
View File
@@ -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<H: Hasher>(&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<DirEntry>;
fn next(&mut self) -> Option<io::Result<DirEntry>> {
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<FileAttr> {
todo!()
}
pub fn file_type(&self) -> io::Result<FileType> {
todo!()
}
}
impl DirBuilder {
pub fn new() -> DirBuilder {
todo!()
}
pub fn mkdir(&self, _p: &Path) -> io::Result<()> {
todo!()
}
}
pub fn readdir(_p: &Path) -> io::Result<ReadDir> {
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<PathBuf> {
todo!()
}
@@ -221,10 +143,6 @@ pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
todo!()
}
pub fn rmdir(_p: &Path) -> io::Result<()> {
todo!()
}
pub fn copy(_from: &Path, _to: &Path) -> io::Result<u64> {
todo!()
}
@@ -27,7 +27,6 @@ impl LocalKey {
#[inline]
pub unsafe fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> 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<unsafe extern "C" fn(*mut u8)>) -> 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)
}