Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

revise the interpretation of ReadDir for HermitOS #124304

Merged
merged 2 commits into from
May 19, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion library/std/src/os/hermit/mod.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

#[allow(unused_extern_crates)]
#[stable(feature = "rust1", since = "1.0.0")]
pub extern crate hermit_abi as abi;
pub extern crate hermit_abi;

pub mod ffi;
pub mod io;
10 changes: 5 additions & 5 deletions library/std/src/sys/pal/hermit/alloc.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use super::abi;
use super::hermit_abi;
use crate::alloc::{GlobalAlloc, Layout, System};
use crate::ptr;

#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
abi::malloc(layout.size(), layout.align())
hermit_abi::malloc(layout.size(), layout.align())
}

unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
let addr = abi::malloc(layout.size(), layout.align());
let addr = hermit_abi::malloc(layout.size(), layout.align());

if !addr.is_null() {
ptr::write_bytes(addr, 0x00, layout.size());
@@ -21,11 +21,11 @@ unsafe impl GlobalAlloc for System {

#[inline]
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
abi::free(ptr, layout.size(), layout.align())
hermit_abi::free(ptr, layout.size(), layout.align())
}

#[inline]
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
abi::realloc(ptr, layout.size(), layout.align(), new_size)
hermit_abi::realloc(ptr, layout.size(), layout.align(), new_size)
}
}
12 changes: 7 additions & 5 deletions library/std/src/sys/pal/hermit/fd.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![unstable(reason = "not public", issue = "none", feature = "fd")]

use super::abi;
use super::hermit_abi;
use crate::io::{self, Read};
use crate::os::hermit::io::{FromRawFd, OwnedFd, RawFd};
use crate::sys::cvt;
@@ -16,7 +16,8 @@ pub struct FileDesc {

impl FileDesc {
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
let result = cvt(unsafe { abi::read(self.fd.as_raw_fd(), buf.as_mut_ptr(), buf.len()) })?;
let result =
cvt(unsafe { hermit_abi::read(self.fd.as_raw_fd(), buf.as_mut_ptr(), buf.len()) })?;
Ok(result as usize)
}

@@ -26,7 +27,8 @@ impl FileDesc {
}

pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
let result = cvt(unsafe { abi::write(self.fd.as_raw_fd(), buf.as_ptr(), buf.len()) })?;
let result =
cvt(unsafe { hermit_abi::write(self.fd.as_raw_fd(), buf.as_ptr(), buf.len()) })?;
Ok(result as usize)
}

@@ -49,8 +51,8 @@ impl FileDesc {
unsupported()
}

pub fn fstat(&self, stat: *mut abi::stat) -> io::Result<()> {
cvt(unsafe { abi::fstat(self.fd.as_raw_fd(), stat) })?;
pub fn fstat(&self, stat: *mut hermit_abi::stat) -> io::Result<()> {
cvt(unsafe { hermit_abi::fstat(self.fd.as_raw_fd(), stat) })?;
Ok(())
}
}
51 changes: 23 additions & 28 deletions library/std/src/sys/pal/hermit/fs.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::abi::{
use super::fd::FileDesc;
use super::hermit_abi::{
self, dirent64, stat as stat_struct, DT_DIR, DT_LNK, DT_REG, DT_UNKNOWN, O_APPEND, O_CREAT,
O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, S_IFDIR, S_IFLNK, S_IFMT, S_IFREG,
};
use super::fd::FileDesc;
use crate::ffi::{CStr, OsStr, OsString};
use crate::fmt;
use crate::io::{self, Error, ErrorKind};
@@ -47,7 +47,7 @@ impl InnerReadDir {

pub struct ReadDir {
inner: Arc<InnerReadDir>,
pos: i64,
pos: usize,
}

impl ReadDir {
@@ -197,38 +197,31 @@ impl Iterator for ReadDir {

fn next(&mut self) -> Option<io::Result<DirEntry>> {
let mut counter: usize = 0;
let mut offset: i64 = 0;
let mut offset: usize = 0;

// loop over all directory entries and search the entry for the current position
loop {
// leave function, if the loop reaches the of the buffer (with all entries)
if offset >= self.inner.dir.len().try_into().unwrap() {
if offset >= self.inner.dir.len() {
return None;
}

let dir = unsafe {
&*(self.inner.dir.as_ptr().offset(offset.try_into().unwrap()) as *const dirent64)
};
let dir = unsafe { &*(self.inner.dir.as_ptr().add(offset) as *const dirent64) };

if counter == self.pos.try_into().unwrap() {
if counter == self.pos {
self.pos += 1;

// After dirent64, the file name is stored. d_reclen represents the length of the dirent64
// plus the length of the file name. Consequently, file name has a size of d_reclen minus
// the size of dirent64. The file name is always a C string and terminated by `\0`.
// Consequently, we are able to ignore the last byte.
let name_bytes = unsafe {
core::slice::from_raw_parts(
&dir.d_name as *const _ as *const u8,
dir.d_reclen as usize - core::mem::size_of::<dirent64>() - 1,
)
.to_vec()
};
let name_bytes =
unsafe { CStr::from_ptr(&dir.d_name as *const _ as *const i8).to_bytes() };
let entry = DirEntry {
root: self.inner.root.clone(),
ino: dir.d_ino,
type_: dir.d_type as u32,
name: OsString::from_vec(name_bytes),
name: OsString::from_vec(name_bytes.to_vec()),
};

return Some(Ok(entry));
@@ -237,7 +230,7 @@ impl Iterator for ReadDir {
counter += 1;

// move to the next dirent64, which is directly stored after the previous one
offset = offset + dir.d_off;
offset = offset + usize::from(dir.d_reclen);
}
}
}
@@ -365,7 +358,7 @@ impl File {
mode = 0;
}

let fd = unsafe { cvt(abi::open(path.as_ptr(), flags, mode))? };
let fd = unsafe { cvt(hermit_abi::open(path.as_ptr(), flags, mode))? };
Ok(File(unsafe { FileDesc::from_raw_fd(fd as i32) }))
}

@@ -446,7 +439,7 @@ impl DirBuilder {

pub fn mkdir(&self, path: &Path) -> io::Result<()> {
run_path_with_cstr(path, &|path| {
cvt(unsafe { abi::mkdir(path.as_ptr(), self.mode) }).map(|_| ())
cvt(unsafe { hermit_abi::mkdir(path.as_ptr(), self.mode) }).map(|_| ())
})
}

@@ -508,7 +501,8 @@ impl FromRawFd for File {
}

pub fn readdir(path: &Path) -> io::Result<ReadDir> {
let fd_raw = run_path_with_cstr(path, &|path| cvt(unsafe { abi::opendir(path.as_ptr()) }))?;
let fd_raw =
run_path_with_cstr(path, &|path| cvt(unsafe { hermit_abi::opendir(path.as_ptr()) }))?;
let fd = unsafe { FileDesc::from_raw_fd(fd_raw as i32) };
let root = path.to_path_buf();

@@ -519,8 +513,9 @@ pub fn readdir(path: &Path) -> io::Result<ReadDir> {
// reserve memory to receive all directory entries
vec.resize(sz, 0);

let readlen =
unsafe { abi::getdents64(fd.as_raw_fd(), vec.as_mut_ptr() as *mut dirent64, sz) };
let readlen = unsafe {
hermit_abi::getdents64(fd.as_raw_fd(), vec.as_mut_ptr() as *mut dirent64, sz)
};
if readlen > 0 {
// shrink down to the minimal size
vec.resize(readlen.try_into().unwrap(), 0);
@@ -529,7 +524,7 @@ pub fn readdir(path: &Path) -> io::Result<ReadDir> {

// if the buffer is too small, getdents64 returns EINVAL
// otherwise, getdents64 returns an error number
if readlen != (-abi::errno::EINVAL).into() {
if readlen != (-hermit_abi::errno::EINVAL).into() {
return Err(Error::from_raw_os_error(readlen.try_into().unwrap()));
}

@@ -547,7 +542,7 @@ pub fn readdir(path: &Path) -> io::Result<ReadDir> {
}

pub fn unlink(path: &Path) -> io::Result<()> {
run_path_with_cstr(path, &|path| cvt(unsafe { abi::unlink(path.as_ptr()) }).map(|_| ()))
run_path_with_cstr(path, &|path| cvt(unsafe { hermit_abi::unlink(path.as_ptr()) }).map(|_| ()))
}

pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> {
@@ -559,7 +554,7 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> {
}

pub fn rmdir(path: &Path) -> io::Result<()> {
run_path_with_cstr(path, &|path| cvt(unsafe { abi::rmdir(path.as_ptr()) }).map(|_| ()))
run_path_with_cstr(path, &|path| cvt(unsafe { hermit_abi::rmdir(path.as_ptr()) }).map(|_| ()))
}

pub fn remove_dir_all(_path: &Path) -> io::Result<()> {
@@ -581,15 +576,15 @@ pub fn link(_original: &Path, _link: &Path) -> io::Result<()> {
pub fn stat(path: &Path) -> io::Result<FileAttr> {
run_path_with_cstr(path, &|path| {
let mut stat_val: stat_struct = unsafe { mem::zeroed() };
cvt(unsafe { abi::stat(path.as_ptr(), &mut stat_val) })?;
cvt(unsafe { hermit_abi::stat(path.as_ptr(), &mut stat_val) })?;
Ok(FileAttr::from_stat(stat_val))
})
}

pub fn lstat(path: &Path) -> io::Result<FileAttr> {
run_path_with_cstr(path, &|path| {
let mut stat_val: stat_struct = unsafe { mem::zeroed() };
cvt(unsafe { abi::lstat(path.as_ptr(), &mut stat_val) })?;
cvt(unsafe { hermit_abi::lstat(path.as_ptr(), &mut stat_val) })?;
Ok(FileAttr::from_stat(stat_val))
})
}
16 changes: 8 additions & 8 deletions library/std/src/sys/pal/hermit/futex.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::abi;
use super::hermit_abi;
use crate::ptr::null;
use crate::sync::atomic::AtomicU32;
use crate::time::Duration;
@@ -8,32 +8,32 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -
//
// Overflows are rounded up to an infinite timeout (None).
let timespec = timeout.and_then(|dur| {
Some(abi::timespec {
Some(hermit_abi::timespec {
tv_sec: dur.as_secs().try_into().ok()?,
tv_nsec: dur.subsec_nanos().into(),
})
});

let r = unsafe {
abi::futex_wait(
hermit_abi::futex_wait(
futex.as_ptr(),
expected,
timespec.as_ref().map_or(null(), |t| t as *const abi::timespec),
abi::FUTEX_RELATIVE_TIMEOUT,
timespec.as_ref().map_or(null(), |t| t as *const hermit_abi::timespec),
hermit_abi::FUTEX_RELATIVE_TIMEOUT,
)
};

r != -abi::errno::ETIMEDOUT
r != -hermit_abi::errno::ETIMEDOUT
}

#[inline]
pub fn futex_wake(futex: &AtomicU32) -> bool {
unsafe { abi::futex_wake(futex.as_ptr(), 1) > 0 }
unsafe { hermit_abi::futex_wake(futex.as_ptr(), 1) > 0 }
}

#[inline]
pub fn futex_wake_all(futex: &AtomicU32) {
unsafe {
abi::futex_wake(futex.as_ptr(), i32::MAX);
hermit_abi::futex_wake(futex.as_ptr(), i32::MAX);
}
}
40 changes: 20 additions & 20 deletions library/std/src/sys/pal/hermit/mod.rs
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ pub mod thread_local_key;
pub mod time;

use crate::io::ErrorKind;
use crate::os::hermit::abi;
use crate::os::hermit::hermit_abi;

pub fn unsupported<T>() -> crate::io::Result<T> {
Err(unsupported_err())
@@ -54,15 +54,15 @@ pub fn unsupported_err() -> crate::io::Error {

pub fn abort_internal() -> ! {
unsafe {
abi::abort();
hermit_abi::abort();
}
}

pub fn hashmap_random_keys() -> (u64, u64) {
let mut buf = [0; 16];
let mut slice = &mut buf[..];
while !slice.is_empty() {
let res = cvt(unsafe { abi::read_entropy(slice.as_mut_ptr(), slice.len(), 0) })
let res = cvt(unsafe { hermit_abi::read_entropy(slice.as_mut_ptr(), slice.len(), 0) })
.expect("failed to generate random hashmap keys");
slice = &mut slice[res as usize..];
}
@@ -109,31 +109,31 @@ pub unsafe extern "C" fn runtime_entry(
let result = main(argc as isize, argv);

run_dtors();
abi::exit(result);
hermit_abi::exit(result);
}

#[inline]
pub(crate) fn is_interrupted(errno: i32) -> bool {
errno == abi::errno::EINTR
errno == hermit_abi::errno::EINTR
}

pub fn decode_error_kind(errno: i32) -> ErrorKind {
match errno {
abi::errno::EACCES => ErrorKind::PermissionDenied,
abi::errno::EADDRINUSE => ErrorKind::AddrInUse,
abi::errno::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
abi::errno::EAGAIN => ErrorKind::WouldBlock,
abi::errno::ECONNABORTED => ErrorKind::ConnectionAborted,
abi::errno::ECONNREFUSED => ErrorKind::ConnectionRefused,
abi::errno::ECONNRESET => ErrorKind::ConnectionReset,
abi::errno::EEXIST => ErrorKind::AlreadyExists,
abi::errno::EINTR => ErrorKind::Interrupted,
abi::errno::EINVAL => ErrorKind::InvalidInput,
abi::errno::ENOENT => ErrorKind::NotFound,
abi::errno::ENOTCONN => ErrorKind::NotConnected,
abi::errno::EPERM => ErrorKind::PermissionDenied,
abi::errno::EPIPE => ErrorKind::BrokenPipe,
abi::errno::ETIMEDOUT => ErrorKind::TimedOut,
hermit_abi::errno::EACCES => ErrorKind::PermissionDenied,
hermit_abi::errno::EADDRINUSE => ErrorKind::AddrInUse,
hermit_abi::errno::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
hermit_abi::errno::EAGAIN => ErrorKind::WouldBlock,
hermit_abi::errno::ECONNABORTED => ErrorKind::ConnectionAborted,
hermit_abi::errno::ECONNREFUSED => ErrorKind::ConnectionRefused,
hermit_abi::errno::ECONNRESET => ErrorKind::ConnectionReset,
hermit_abi::errno::EEXIST => ErrorKind::AlreadyExists,
hermit_abi::errno::EINTR => ErrorKind::Interrupted,
hermit_abi::errno::EINVAL => ErrorKind::InvalidInput,
hermit_abi::errno::ENOENT => ErrorKind::NotFound,
hermit_abi::errno::ENOTCONN => ErrorKind::NotConnected,
hermit_abi::errno::EPERM => ErrorKind::PermissionDenied,
hermit_abi::errno::EPIPE => ErrorKind::BrokenPipe,
hermit_abi::errno::ETIMEDOUT => ErrorKind::TimedOut,
_ => ErrorKind::Uncategorized,
}
}
10 changes: 5 additions & 5 deletions library/std/src/sys/pal/hermit/os.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::abi;
use super::hermit_abi;
use crate::collections::HashMap;
use crate::error::Error as StdError;
use crate::ffi::{CStr, OsStr, OsString};
@@ -14,11 +14,11 @@ use crate::vec;
use core::slice::memchr;

pub fn errno() -> i32 {
unsafe { abi::get_errno() }
unsafe { hermit_abi::get_errno() }
}

pub fn error_string(errno: i32) -> String {
abi::error_string(errno).to_string()
hermit_abi::error_string(errno).to_string()
}

pub fn getcwd() -> io::Result<PathBuf> {
@@ -197,10 +197,10 @@ pub fn home_dir() -> Option<PathBuf> {

pub fn exit(code: i32) -> ! {
unsafe {
abi::exit(code);
hermit_abi::exit(code);
}
}

pub fn getpid() -> u32 {
unsafe { abi::getpid() }
unsafe { hermit_abi::getpid() }
}
Loading
Loading