Fast-forward snapshot_0 to match wasi-common upstream
While we are waiting for the Rust toolchain to use the new ABI, I thought it might be useful to sync `snapshot_0` with the latest code in `wasi-common` "upstream". This mainly includes the latest refactoring effort to unify the machinery for `fd_readdir` between Linux, Windows and BSD.
This commit is contained in:
@@ -1,16 +1,15 @@
|
||||
// Based on src/dir.rs from nix
|
||||
#![allow(unused)] // temporarily, until BSD catches up with this change
|
||||
use crate::old::snapshot_0::hostcalls_impl::FileType;
|
||||
use libc;
|
||||
use nix::{errno::Errno, Error, Result};
|
||||
use nix::{Error, Result};
|
||||
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
|
||||
use std::{ffi, ptr};
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
use libc::{dirent64 as dirent, readdir64_r as readdir_r};
|
||||
use libc::dirent64 as dirent;
|
||||
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
use libc::{dirent, readdir_r};
|
||||
#[cfg(not(target_os = "linux",))]
|
||||
use libc::dirent;
|
||||
|
||||
/// An open directory.
|
||||
///
|
||||
@@ -26,7 +25,7 @@ use libc::{dirent, readdir_r};
|
||||
/// * returns entries' names as a `CStr` (no allocation or conversion beyond whatever libc
|
||||
/// does).
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
pub(crate) struct Dir(ptr::NonNull<libc::DIR>);
|
||||
pub(crate) struct Dir(pub(crate) ptr::NonNull<libc::DIR>);
|
||||
|
||||
impl Dir {
|
||||
/// Converts from a descriptor-based object, closing the descriptor on success or failure.
|
||||
@@ -90,53 +89,12 @@ impl Drop for Dir {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct IntoIter(Dir);
|
||||
impl Iterator for IntoIter {
|
||||
type Item = Result<Entry>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
unsafe {
|
||||
// Note: POSIX specifies that portable applications should dynamically allocate a
|
||||
// buffer with room for a `d_name` field of size `pathconf(..., _PC_NAME_MAX)` plus 1
|
||||
// for the NUL byte. It doesn't look like the std library does this; it just uses
|
||||
// fixed-sized buffers (and libc's dirent seems to be sized so this is appropriate).
|
||||
// Probably fine here too then.
|
||||
//
|
||||
// See `impl Iterator for ReadDir` [1] for more details.
|
||||
// [1] https://github.com/rust-lang/rust/blob/master/src/libstd/sys/unix/fs.rs
|
||||
let mut ent = std::mem::MaybeUninit::<dirent>::uninit();
|
||||
let mut result = ptr::null_mut();
|
||||
if let Err(e) = Errno::result(readdir_r(
|
||||
(self.0).0.as_ptr(),
|
||||
ent.as_mut_ptr(),
|
||||
&mut result,
|
||||
)) {
|
||||
return Some(Err(e));
|
||||
}
|
||||
if result.is_null() {
|
||||
None
|
||||
} else {
|
||||
assert_eq!(result, ent.as_mut_ptr(), "readdir_r specification violated");
|
||||
Some(Ok(Entry(ent.assume_init())))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for Dir {
|
||||
type IntoIter = IntoIter;
|
||||
type Item = Result<Entry>;
|
||||
|
||||
fn into_iter(self) -> IntoIter {
|
||||
IntoIter(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// A directory entry, similar to `std::fs::DirEntry`.
|
||||
///
|
||||
/// Note that unlike the std version, this may represent the `.` or `..` entries.
|
||||
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[repr(transparent)]
|
||||
pub(crate) struct Entry(dirent);
|
||||
pub(crate) struct Entry(pub(crate) dirent);
|
||||
|
||||
pub(crate) type Type = FileType;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user