alnyan/yggdrasil: directory read implementation
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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!()
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user