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
Show file tree
Hide file tree
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
Expand Up @@ -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;
Expand Down
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());
Expand All @@ -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;
Expand All @@ -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)
}

Expand All @@ -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)
}

Expand All @@ -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(())
}
}
Expand Down
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};
Expand Down Expand Up @@ -47,7 +47,7 @@ impl InnerReadDir {

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

impl ReadDir {
Expand Down Expand Up @@ -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));
Expand All @@ -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);
}
}
}
Expand Down Expand Up @@ -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) }))
}

Expand Down Expand Up @@ -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(|_| ())
})
}

Expand Down Expand Up @@ -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();

Expand All @@ -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);
Expand All @@ -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()));
}

Expand All @@ -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<()> {
Expand All @@ -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<()> {
Expand All @@ -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))
})
}
Expand Down
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;
Expand All @@ -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
Expand Up @@ -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())
Expand All @@ -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..];
}
Expand Down Expand Up @@ -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,
}
}
Expand Down
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};
Expand All @@ -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> {
Expand Down Expand Up @@ -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