Skip to content

Commit

Permalink
Rollup merge of rust-lang#124304 - hermit-os:fuse, r=joboet
Browse files Browse the repository at this point in the history
revise the interpretation of ReadDir for HermitOS

HermitOS supports getdents64. As under Linux, the dirent64 entry `d_off` is not longer used, because its definition is not clear. Instead of `d_off` the entry `d_reclen` is used to determine the end of the dirent64 entry.

In addition, take up `@workingjubilee`  suggestion from the discussions in rust-lang#115984 to increase the readability.

Hermit is a tier 3 platform and this PR changes only files, wich are related to the tier 3 platform.
  • Loading branch information
compiler-errors authored May 19, 2024
2 parents 0f923a4 + 5aa779f commit f848505
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 90 deletions.
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

0 comments on commit f848505

Please sign in to comment.