diff options
| author | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 | 
|---|---|---|
| committer | Valentin Popov <valentin@popov.link> | 2024-07-19 15:37:58 +0300 | 
| commit | a990de90fe41456a23e58bd087d2f107d321f3a1 (patch) | |
| tree | 15afc392522a9e85dc3332235e311b7d39352ea9 /vendor/rustix/src/backend/libc/fs | |
| parent | 3d48cd3f81164bbfc1a755dc1d4a9a02f98c8ddd (diff) | |
| download | fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.tar.xz fparkan-a990de90fe41456a23e58bd087d2f107d321f3a1.zip  | |
Deleted vendor folder
Diffstat (limited to 'vendor/rustix/src/backend/libc/fs')
| -rw-r--r-- | vendor/rustix/src/backend/libc/fs/dir.rs | 423 | ||||
| -rw-r--r-- | vendor/rustix/src/backend/libc/fs/inotify.rs | 131 | ||||
| -rw-r--r-- | vendor/rustix/src/backend/libc/fs/makedev.rs | 138 | ||||
| -rw-r--r-- | vendor/rustix/src/backend/libc/fs/mod.rs | 23 | ||||
| -rw-r--r-- | vendor/rustix/src/backend/libc/fs/syscalls.rs | 2514 | ||||
| -rw-r--r-- | vendor/rustix/src/backend/libc/fs/types.rs | 1164 | 
6 files changed, 0 insertions, 4393 deletions
diff --git a/vendor/rustix/src/backend/libc/fs/dir.rs b/vendor/rustix/src/backend/libc/fs/dir.rs deleted file mode 100644 index 82a0a90..0000000 --- a/vendor/rustix/src/backend/libc/fs/dir.rs +++ /dev/null @@ -1,423 +0,0 @@ -#[cfg(not(any(solarish, target_os = "haiku", target_os = "nto", target_os = "vita")))] -use super::types::FileType; -use crate::backend::c; -use crate::backend::conv::owned_fd; -use crate::fd::{AsFd, BorrowedFd, OwnedFd}; -use crate::ffi::{CStr, CString}; -use crate::fs::{fcntl_getfl, openat, Mode, OFlags}; -#[cfg(not(target_os = "vita"))] -use crate::fs::{fstat, Stat}; -#[cfg(not(any( -    solarish, -    target_os = "haiku", -    target_os = "netbsd", -    target_os = "nto", -    target_os = "redox", -    target_os = "vita", -    target_os = "wasi", -)))] -use crate::fs::{fstatfs, StatFs}; -#[cfg(not(any( -    solarish, -    target_os = "haiku", -    target_os = "redox", -    target_os = "vita", -    target_os = "wasi" -)))] -use crate::fs::{fstatvfs, StatVfs}; -use crate::io; -#[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] -#[cfg(feature = "process")] -use crate::process::fchdir; -use alloc::borrow::ToOwned; -#[cfg(not(any(linux_like, target_os = "hurd")))] -use c::readdir as libc_readdir; -#[cfg(any(linux_like, target_os = "hurd"))] -use c::readdir64 as libc_readdir; -use core::fmt; -use core::ptr::NonNull; -use libc_errno::{errno, set_errno, Errno}; - -/// `DIR*` -pub struct Dir { -    /// The `libc` `DIR` pointer. -    libc_dir: NonNull<c::DIR>, - -    /// Have we seen any errors in this iteration? -    any_errors: bool, -} - -impl Dir { -    /// Take ownership of `fd` and construct a `Dir` that reads entries from -    /// the given directory file descriptor. -    #[inline] -    pub fn new<Fd: Into<OwnedFd>>(fd: Fd) -> io::Result<Self> { -        Self::_new(fd.into()) -    } - -    #[inline] -    fn _new(fd: OwnedFd) -> io::Result<Self> { -        let raw = owned_fd(fd); -        unsafe { -            let libc_dir = c::fdopendir(raw); - -            if let Some(libc_dir) = NonNull::new(libc_dir) { -                Ok(Self { -                    libc_dir, -                    any_errors: false, -                }) -            } else { -                let err = io::Errno::last_os_error(); -                let _ = c::close(raw); -                Err(err) -            } -        } -    } - -    /// Borrow `fd` and construct a `Dir` that reads entries from the given -    /// directory file descriptor. -    #[inline] -    pub fn read_from<Fd: AsFd>(fd: Fd) -> io::Result<Self> { -        Self::_read_from(fd.as_fd()) -    } - -    #[inline] -    #[allow(unused_mut)] -    fn _read_from(fd: BorrowedFd<'_>) -> io::Result<Self> { -        let mut any_errors = false; - -        // Given an arbitrary `OwnedFd`, it's impossible to know whether the -        // user holds a `dup`'d copy which could continue to modify the -        // file description state, which would cause Undefined Behavior after -        // our call to `fdopendir`. To prevent this, we obtain an independent -        // `OwnedFd`. -        let flags = fcntl_getfl(fd)?; -        let fd_for_dir = match openat(fd, cstr!("."), flags | OFlags::CLOEXEC, Mode::empty()) { -            Ok(fd) => fd, -            #[cfg(not(target_os = "wasi"))] -            Err(io::Errno::NOENT) => { -                // If "." doesn't exist, it means the directory was removed. -                // We treat that as iterating through a directory with no -                // entries. -                any_errors = true; -                crate::io::dup(fd)? -            } -            Err(err) => return Err(err), -        }; - -        let raw = owned_fd(fd_for_dir); -        unsafe { -            let libc_dir = c::fdopendir(raw); - -            if let Some(libc_dir) = NonNull::new(libc_dir) { -                Ok(Self { -                    libc_dir, -                    any_errors, -                }) -            } else { -                let err = io::Errno::last_os_error(); -                let _ = c::close(raw); -                Err(err) -            } -        } -    } - -    /// `rewinddir(self)` -    #[inline] -    pub fn rewind(&mut self) { -        self.any_errors = false; -        unsafe { c::rewinddir(self.libc_dir.as_ptr()) } -    } - -    /// `readdir(self)`, where `None` means the end of the directory. -    pub fn read(&mut self) -> Option<io::Result<DirEntry>> { -        // If we've seen errors, don't continue to try to read anyting further. -        if self.any_errors { -            return None; -        } - -        set_errno(Errno(0)); -        let dirent_ptr = unsafe { libc_readdir(self.libc_dir.as_ptr()) }; -        if dirent_ptr.is_null() { -            let curr_errno = errno().0; -            if curr_errno == 0 { -                // We successfully reached the end of the stream. -                None -            } else { -                // `errno` is unknown or non-zero, so an error occurred. -                self.any_errors = true; -                Some(Err(io::Errno(curr_errno))) -            } -        } else { -            // We successfully read an entry. -            unsafe { -                let dirent = &*dirent_ptr; - -                // We have our own copy of OpenBSD's dirent; check that the -                // layout minimally matches libc's. -                #[cfg(target_os = "openbsd")] -                check_dirent_layout(dirent); - -                let result = DirEntry { -                    #[cfg(not(any( -                        solarish, -                        target_os = "aix", -                        target_os = "haiku", -                        target_os = "nto", -                        target_os = "vita" -                    )))] -                    d_type: dirent.d_type, - -                    #[cfg(not(any(freebsdlike, netbsdlike, target_os = "vita")))] -                    d_ino: dirent.d_ino, - -                    #[cfg(any(freebsdlike, netbsdlike))] -                    d_fileno: dirent.d_fileno, - -                    name: CStr::from_ptr(dirent.d_name.as_ptr()).to_owned(), -                }; - -                Some(Ok(result)) -            } -        } -    } - -    /// `fstat(self)` -    #[cfg(not(target_os = "vita"))] -    #[inline] -    pub fn stat(&self) -> io::Result<Stat> { -        fstat(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.libc_dir.as_ptr())) }) -    } - -    /// `fstatfs(self)` -    #[cfg(not(any( -        solarish, -        target_os = "haiku", -        target_os = "netbsd", -        target_os = "nto", -        target_os = "redox", -        target_os = "vita", -        target_os = "wasi", -    )))] -    #[inline] -    pub fn statfs(&self) -> io::Result<StatFs> { -        fstatfs(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.libc_dir.as_ptr())) }) -    } - -    /// `fstatvfs(self)` -    #[cfg(not(any( -        solarish, -        target_os = "haiku", -        target_os = "redox", -        target_os = "vita", -        target_os = "wasi" -    )))] -    #[inline] -    pub fn statvfs(&self) -> io::Result<StatVfs> { -        fstatvfs(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.libc_dir.as_ptr())) }) -    } - -    /// `fchdir(self)` -    #[cfg(feature = "process")] -    #[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] -    #[cfg_attr(doc_cfg, doc(cfg(feature = "process")))] -    #[inline] -    pub fn chdir(&self) -> io::Result<()> { -        fchdir(unsafe { BorrowedFd::borrow_raw(c::dirfd(self.libc_dir.as_ptr())) }) -    } -} - -/// `Dir` implements `Send` but not `Sync`, because we use `readdir` which is -/// not guaranteed to be thread-safe. Users can wrap this in a `Mutex` if they -/// need `Sync`, which is effectively what'd need to do to implement `Sync` -/// ourselves. -unsafe impl Send for Dir {} - -impl Drop for Dir { -    #[inline] -    fn drop(&mut self) { -        unsafe { c::closedir(self.libc_dir.as_ptr()) }; -    } -} - -impl Iterator for Dir { -    type Item = io::Result<DirEntry>; - -    #[inline] -    fn next(&mut self) -> Option<Self::Item> { -        Self::read(self) -    } -} - -impl fmt::Debug for Dir { -    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -        let mut s = f.debug_struct("Dir"); -        #[cfg(not(target_os = "vita"))] -        s.field("fd", unsafe { &c::dirfd(self.libc_dir.as_ptr()) }); -        s.finish() -    } -} - -/// `struct dirent` -#[derive(Debug)] -pub struct DirEntry { -    #[cfg(not(any( -        solarish, -        target_os = "aix", -        target_os = "haiku", -        target_os = "nto", -        target_os = "vita" -    )))] -    d_type: u8, - -    #[cfg(not(any(freebsdlike, netbsdlike, target_os = "vita")))] -    d_ino: c::ino_t, - -    #[cfg(any(freebsdlike, netbsdlike))] -    d_fileno: c::ino_t, - -    name: CString, -} - -impl DirEntry { -    /// Returns the file name of this directory entry. -    #[inline] -    pub fn file_name(&self) -> &CStr { -        &self.name -    } - -    /// Returns the type of this directory entry. -    #[cfg(not(any( -        solarish, -        target_os = "aix", -        target_os = "haiku", -        target_os = "nto", -        target_os = "vita" -    )))] -    #[inline] -    pub fn file_type(&self) -> FileType { -        FileType::from_dirent_d_type(self.d_type) -    } - -    /// Return the inode number of this directory entry. -    #[cfg(not(any(freebsdlike, netbsdlike, target_os = "vita")))] -    #[inline] -    pub fn ino(&self) -> u64 { -        self.d_ino as u64 -    } - -    /// Return the inode number of this directory entry. -    #[cfg(any(freebsdlike, netbsdlike))] -    #[inline] -    pub fn ino(&self) -> u64 { -        #[allow(clippy::useless_conversion)] -        self.d_fileno.into() -    } -} - -/// libc's OpenBSD `dirent` has a private field so we can't construct it -/// directly, so we declare it ourselves to make all fields accessible. -#[cfg(target_os = "openbsd")] -#[repr(C)] -#[derive(Debug)] -struct libc_dirent { -    d_fileno: c::ino_t, -    d_off: c::off_t, -    d_reclen: u16, -    d_type: u8, -    d_namlen: u8, -    __d_padding: [u8; 4], -    d_name: [c::c_char; 256], -} - -/// We have our own copy of OpenBSD's dirent; check that the layout -/// minimally matches libc's. -#[cfg(target_os = "openbsd")] -fn check_dirent_layout(dirent: &c::dirent) { -    use crate::utils::as_ptr; - -    // Check that the basic layouts match. -    #[cfg(test)] -    { -        assert_eq_size!(libc_dirent, c::dirent); -        assert_eq_size!(libc_dirent, c::dirent); -    } - -    // Check that the field offsets match. -    assert_eq!( -        { -            let z = libc_dirent { -                d_fileno: 0_u64, -                d_off: 0_i64, -                d_reclen: 0_u16, -                d_type: 0_u8, -                d_namlen: 0_u8, -                __d_padding: [0_u8; 4], -                d_name: [0 as c::c_char; 256], -            }; -            let base = as_ptr(&z) as usize; -            ( -                (as_ptr(&z.d_fileno) as usize) - base, -                (as_ptr(&z.d_off) as usize) - base, -                (as_ptr(&z.d_reclen) as usize) - base, -                (as_ptr(&z.d_type) as usize) - base, -                (as_ptr(&z.d_namlen) as usize) - base, -                (as_ptr(&z.d_name) as usize) - base, -            ) -        }, -        { -            let z = dirent; -            let base = as_ptr(z) as usize; -            ( -                (as_ptr(&z.d_fileno) as usize) - base, -                (as_ptr(&z.d_off) as usize) - base, -                (as_ptr(&z.d_reclen) as usize) - base, -                (as_ptr(&z.d_type) as usize) - base, -                (as_ptr(&z.d_namlen) as usize) - base, -                (as_ptr(&z.d_name) as usize) - base, -            ) -        } -    ); -} - -#[test] -fn dir_iterator_handles_io_errors() { -    // create a dir, keep the FD, then delete the dir -    let tmp = tempfile::tempdir().unwrap(); -    let fd = crate::fs::openat( -        crate::fs::CWD, -        tmp.path(), -        crate::fs::OFlags::RDONLY | crate::fs::OFlags::CLOEXEC, -        crate::fs::Mode::empty(), -    ) -    .unwrap(); - -    let file_fd = crate::fs::openat( -        &fd, -        tmp.path().join("test.txt"), -        crate::fs::OFlags::WRONLY | crate::fs::OFlags::CREATE, -        crate::fs::Mode::RWXU, -    ) -    .unwrap(); - -    let mut dir = Dir::read_from(&fd).unwrap(); - -    // Reach inside the `Dir` and replace its directory with a file, which -    // will cause the subsequent `readdir` to fail. -    unsafe { -        let raw_fd = c::dirfd(dir.libc_dir.as_ptr()); -        let mut owned_fd: crate::fd::OwnedFd = crate::fd::FromRawFd::from_raw_fd(raw_fd); -        crate::io::dup2(&file_fd, &mut owned_fd).unwrap(); -        core::mem::forget(owned_fd); -    } - -    // FreeBSD and macOS seem to read some directory entries before we call -    // `.next()`. -    #[cfg(any(apple, freebsdlike))] -    { -        dir.rewind(); -    } - -    assert!(matches!(dir.next(), Some(Err(_)))); -    assert!(dir.next().is_none()); -} diff --git a/vendor/rustix/src/backend/libc/fs/inotify.rs b/vendor/rustix/src/backend/libc/fs/inotify.rs deleted file mode 100644 index 2044bd9..0000000 --- a/vendor/rustix/src/backend/libc/fs/inotify.rs +++ /dev/null @@ -1,131 +0,0 @@ -//! inotify support for working with inotifies - -use crate::backend::c; -use crate::backend::conv::{borrowed_fd, c_str, ret, ret_c_int, ret_owned_fd}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::io; -use bitflags::bitflags; - -bitflags! { -    /// `IN_*` for use with [`inotify_init`]. -    /// -    /// [`inotify_init`]: crate::fs::inotify::inotify_init -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct CreateFlags: u32 { -        /// `IN_CLOEXEC` -        const CLOEXEC = bitcast!(c::IN_CLOEXEC); -        /// `IN_NONBLOCK` -        const NONBLOCK = bitcast!(c::IN_NONBLOCK); - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -bitflags! { -    /// `IN*` for use with [`inotify_add_watch`]. -    /// -    /// [`inotify_add_watch`]: crate::fs::inotify::inotify_add_watch -    #[repr(transparent)] -    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct WatchFlags: u32 { -        /// `IN_ACCESS` -        const ACCESS = c::IN_ACCESS; -        /// `IN_ATTRIB` -        const ATTRIB = c::IN_ATTRIB; -        /// `IN_CLOSE_NOWRITE` -        const CLOSE_NOWRITE = c::IN_CLOSE_NOWRITE; -        /// `IN_CLOSE_WRITE` -        const CLOSE_WRITE = c::IN_CLOSE_WRITE; -        /// `IN_CREATE` -        const CREATE = c::IN_CREATE; -        /// `IN_DELETE` -        const DELETE = c::IN_DELETE; -        /// `IN_DELETE_SELF` -        const DELETE_SELF = c::IN_DELETE_SELF; -        /// `IN_MODIFY` -        const MODIFY = c::IN_MODIFY; -        /// `IN_MOVE_SELF` -        const MOVE_SELF = c::IN_MOVE_SELF; -        /// `IN_MOVED_FROM` -        const MOVED_FROM = c::IN_MOVED_FROM; -        /// `IN_MOVED_TO` -        const MOVED_TO = c::IN_MOVED_TO; -        /// `IN_OPEN` -        const OPEN = c::IN_OPEN; - -        /// `IN_CLOSE` -        const CLOSE = c::IN_CLOSE; -        /// `IN_MOVE` -        const MOVE = c::IN_MOVE; -        /// `IN_ALL_EVENTS` -        const ALL_EVENTS = c::IN_ALL_EVENTS; - -        /// `IN_DONT_FOLLOW` -        const DONT_FOLLOW = c::IN_DONT_FOLLOW; -        /// `IN_EXCL_UNLINK` -        const EXCL_UNLINK = 1; -        /// `IN_MASK_ADD` -        const MASK_ADD = 1; -        /// `IN_MASK_CREATE` -        const MASK_CREATE = 1; -        /// `IN_ONESHOT` -        const ONESHOT = c::IN_ONESHOT; -        /// `IN_ONLYDIR` -        const ONLYDIR = c::IN_ONLYDIR; - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -/// `inotify_init1(flags)`—Creates a new inotify object. -/// -/// Use the [`CreateFlags::CLOEXEC`] flag to prevent the resulting file -/// descriptor from being implicitly passed across `exec` boundaries. -#[doc(alias = "inotify_init1")] -pub fn inotify_init(flags: CreateFlags) -> io::Result<OwnedFd> { -    // SAFETY: `inotify_init1` has no safety preconditions. -    unsafe { ret_owned_fd(c::inotify_init1(bitflags_bits!(flags))) } -} - -/// `inotify_add_watch(self, path, flags)`—Adds a watch to inotify. -/// -/// This registers or updates a watch for the filesystem path `path` and -/// returns a watch descriptor corresponding to this watch. -/// -/// Note: Due to the existence of hardlinks, providing two different paths to -/// this method may result in it returning the same watch descriptor. An -/// application should keep track of this externally to avoid logic errors. -pub fn inotify_add_watch<P: crate::path::Arg>( -    inot: BorrowedFd<'_>, -    path: P, -    flags: WatchFlags, -) -> io::Result<i32> { -    path.into_with_c_str(|path| { -        // SAFETY: The fd and path we are passing is guaranteed valid by the -        // type system. -        unsafe { -            ret_c_int(c::inotify_add_watch( -                borrowed_fd(inot), -                c_str(path), -                flags.bits(), -            )) -        } -    }) -} - -/// `inotify_rm_watch(self, wd)`—Removes a watch from this inotify. -/// -/// The watch descriptor provided should have previously been returned by -/// [`inotify_add_watch`] and not previously have been removed. -#[doc(alias = "inotify_rm_watch")] -pub fn inotify_remove_watch(inot: BorrowedFd<'_>, wd: i32) -> io::Result<()> { -    // Android's `inotify_rm_watch` takes `u32` despite that -    // `inotify_add_watch` expects a `i32`. -    #[cfg(target_os = "android")] -    let wd = wd as u32; -    // SAFETY: The fd is valid and closing an arbitrary wd is valid. -    unsafe { ret(c::inotify_rm_watch(borrowed_fd(inot), wd)) } -} diff --git a/vendor/rustix/src/backend/libc/fs/makedev.rs b/vendor/rustix/src/backend/libc/fs/makedev.rs deleted file mode 100644 index aa12102..0000000 --- a/vendor/rustix/src/backend/libc/fs/makedev.rs +++ /dev/null @@ -1,138 +0,0 @@ -#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] -use crate::backend::c; -use crate::fs::Dev; - -#[cfg(not(any( -    apple, -    solarish, -    target_os = "aix", -    target_os = "android", -    target_os = "emscripten", -)))] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { -    c::makedev(maj, min) -} - -#[cfg(solarish)] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { -    // SAFETY: Solarish's `makedev` is marked unsafe but it isn't doing -    // anything unsafe. -    unsafe { c::makedev(maj, min) } -} - -#[cfg(all(target_os = "android", not(target_pointer_width = "32")))] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { -    c::makedev(maj, min) -} - -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { -    // 32-bit Android's `dev_t` is 32-bit, but its `st_dev` is 64-bit, so we do -    // it ourselves. -    ((u64::from(maj) & 0xffff_f000_u64) << 32) -        | ((u64::from(maj) & 0x0000_0fff_u64) << 8) -        | ((u64::from(min) & 0xffff_ff00_u64) << 12) -        | (u64::from(min) & 0x0000_00ff_u64) -} - -#[cfg(target_os = "emscripten")] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { -    // Emscripten's `makedev` has a 32-bit return value. -    Dev::from(c::makedev(maj, min)) -} - -#[cfg(apple)] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { -    // Apple's `makedev` oddly has signed argument types and is `unsafe`. -    unsafe { c::makedev(maj as i32, min as i32) } -} - -#[cfg(target_os = "aix")] -#[inline] -pub(crate) fn makedev(maj: u32, min: u32) -> Dev { -    // AIX's `makedev` oddly is `unsafe`. -    unsafe { c::makedev(maj, min) } -} - -#[cfg(not(any( -    apple, -    freebsdlike, -    target_os = "android", -    target_os = "emscripten", -    target_os = "netbsd" -)))] -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { -    unsafe { c::major(dev) } -} - -#[cfg(any( -    apple, -    freebsdlike, -    target_os = "netbsd", -    all(target_os = "android", not(target_pointer_width = "32")), -))] -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { -    // On some platforms `major` oddly has signed return types. -    (unsafe { c::major(dev) }) as u32 -} - -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { -    // 32-bit Android's `dev_t` is 32-bit, but its `st_dev` is 64-bit, so we do -    // it ourselves. -    (((dev >> 31 >> 1) & 0xffff_f000) | ((dev >> 8) & 0x0000_0fff)) as u32 -} - -#[cfg(target_os = "emscripten")] -#[inline] -pub(crate) fn major(dev: Dev) -> u32 { -    // Emscripten's `major` has a 32-bit argument value. -    unsafe { c::major(dev as u32) } -} - -#[cfg(not(any( -    apple, -    freebsdlike, -    target_os = "android", -    target_os = "emscripten", -    target_os = "netbsd" -)))] -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { -    unsafe { c::minor(dev) } -} - -#[cfg(any( -    apple, -    freebsdlike, -    target_os = "netbsd", -    all(target_os = "android", not(target_pointer_width = "32")) -))] -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { -    // On some platforms, `minor` oddly has signed return types. -    (unsafe { c::minor(dev) }) as u32 -} - -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { -    // 32-bit Android's `dev_t` is 32-bit, but its `st_dev` is 64-bit, so we do -    // it ourselves. -    (((dev >> 12) & 0xffff_ff00) | (dev & 0x0000_00ff)) as u32 -} - -#[cfg(target_os = "emscripten")] -#[inline] -pub(crate) fn minor(dev: Dev) -> u32 { -    // Emscripten's `minor` has a 32-bit argument value. -    unsafe { c::minor(dev as u32) } -} diff --git a/vendor/rustix/src/backend/libc/fs/mod.rs b/vendor/rustix/src/backend/libc/fs/mod.rs deleted file mode 100644 index c17e863..0000000 --- a/vendor/rustix/src/backend/libc/fs/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -#[cfg(all(feature = "alloc", not(any(target_os = "espidf", target_os = "redox"))))] -pub(crate) mod dir; -#[cfg(linux_kernel)] -pub mod inotify; -#[cfg(not(any( -    target_os = "espidf", -    target_os = "haiku", -    target_os = "redox", -    target_os = "vita", -    target_os = "wasi" -)))] -pub(crate) mod makedev; -#[cfg(not(windows))] -pub(crate) mod syscalls; -pub(crate) mod types; - -// TODO: Fix linux-raw-sys to define ioctl codes for sparc. -#[cfg(all(linux_kernel, any(target_arch = "sparc", target_arch = "sparc64")))] -pub(crate) const EXT4_IOC_RESIZE_FS: crate::ioctl::RawOpcode = 0x8008_6610; - -#[cfg(all(linux_kernel, not(any(target_arch = "sparc", target_arch = "sparc64"))))] -pub(crate) const EXT4_IOC_RESIZE_FS: crate::ioctl::RawOpcode = -    linux_raw_sys::ioctl::EXT4_IOC_RESIZE_FS as crate::ioctl::RawOpcode; diff --git a/vendor/rustix/src/backend/libc/fs/syscalls.rs b/vendor/rustix/src/backend/libc/fs/syscalls.rs deleted file mode 100644 index 70e86cf..0000000 --- a/vendor/rustix/src/backend/libc/fs/syscalls.rs +++ /dev/null @@ -1,2514 +0,0 @@ -//! libc syscalls supporting `rustix::fs`. - -use crate::backend::c; -#[cfg(any( -    not(target_os = "redox"), -    feature = "alloc", -    all(linux_kernel, feature = "procfs") -))] -use crate::backend::conv::ret_usize; -use crate::backend::conv::{borrowed_fd, c_str, ret, ret_c_int, ret_off_t, ret_owned_fd}; -use crate::fd::{BorrowedFd, OwnedFd}; -use crate::ffi::CStr; -#[cfg(all(apple, feature = "alloc"))] -use crate::ffi::CString; -#[cfg(not(any(target_os = "espidf", target_os = "vita")))] -use crate::fs::Access; -#[cfg(not(any( -    apple, -    netbsdlike, -    solarish, -    target_os = "dragonfly", -    target_os = "espidf", -    target_os = "haiku", -    target_os = "redox", -    target_os = "vita", -)))] -use crate::fs::Advice; -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] -use crate::fs::AtFlags; -#[cfg(not(any( -    netbsdlike, -    solarish, -    target_os = "aix", -    target_os = "dragonfly", -    target_os = "espidf", -    target_os = "nto", -    target_os = "redox", -    target_os = "vita", -)))] -use crate::fs::FallocateFlags; -#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] -use crate::fs::FlockOperation; -#[cfg(any(linux_kernel, target_os = "freebsd"))] -use crate::fs::MemfdFlags; -#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] -use crate::fs::SealFlags; -#[cfg(not(any( -    solarish, -    target_os = "espidf", -    target_os = "haiku", -    target_os = "netbsd", -    target_os = "nto", -    target_os = "redox", -    target_os = "vita", -    target_os = "wasi", -)))] -use crate::fs::StatFs; -#[cfg(not(any(target_os = "espidf", target_os = "vita")))] -use crate::fs::Timestamps; -#[cfg(not(any( -    apple, -    target_os = "espidf", -    target_os = "redox", -    target_os = "vita", -    target_os = "wasi" -)))] -use crate::fs::{Dev, FileType}; -use crate::fs::{Mode, OFlags, SeekFrom, Stat}; -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -use crate::fs::{StatVfs, StatVfsMountFlags}; -use crate::io; -#[cfg(all(target_env = "gnu", fix_y2038))] -use crate::timespec::LibcTimespec; -#[cfg(not(target_os = "wasi"))] -use crate::ugid::{Gid, Uid}; -#[cfg(all(apple, feature = "alloc"))] -use alloc::vec; -use core::mem::MaybeUninit; -#[cfg(apple)] -use { -    crate::backend::conv::nonnegative_ret, -    crate::fs::{copyfile_state_t, CloneFlags, CopyfileFlags}, -}; -#[cfg(any(apple, linux_kernel))] -use {crate::fs::XattrFlags, core::mem::size_of, core::ptr::null_mut}; -#[cfg(linux_kernel)] -use { -    crate::fs::{RenameFlags, ResolveFlags, Statx, StatxFlags, CWD}, -    core::ptr::null, -}; - -#[cfg(all(target_env = "gnu", fix_y2038))] -weak!(fn __utimensat64(c::c_int, *const c::c_char, *const LibcTimespec, c::c_int) -> c::c_int); -#[cfg(all(target_env = "gnu", fix_y2038))] -weak!(fn __futimens64(c::c_int, *const LibcTimespec) -> c::c_int); - -/// Use a direct syscall (via libc) for `open`. -/// -/// This is only currently necessary as a workaround for old glibc; see below. -#[cfg(all(unix, target_env = "gnu"))] -fn open_via_syscall(path: &CStr, oflags: OFlags, mode: Mode) -> io::Result<OwnedFd> { -    // Linux on aarch64, loongarch64 and riscv64 has no `open` syscall so use -    // `openat`. -    #[cfg(any( -        target_arch = "aarch64", -        target_arch = "riscv32", -        target_arch = "riscv64", -        target_arch = "csky", -        target_arch = "loongarch64" -    ))] -    { -        openat_via_syscall(CWD, path, oflags, mode) -    } - -    // Use the `open` syscall. -    #[cfg(not(any( -        target_arch = "aarch64", -        target_arch = "riscv32", -        target_arch = "riscv64", -        target_arch = "csky", -        target_arch = "loongarch64" -    )))] -    unsafe { -        syscall! { -            fn open( -                pathname: *const c::c_char, -                oflags: c::c_int, -                mode: c::mode_t -            ) via SYS_open -> c::c_int -        } - -        ret_owned_fd(open( -            c_str(path), -            bitflags_bits!(oflags), -            bitflags_bits!(mode), -        )) -    } -} - -pub(crate) fn open(path: &CStr, oflags: OFlags, mode: Mode) -> io::Result<OwnedFd> { -    // Work around <https://sourceware.org/bugzilla/show_bug.cgi?id=17523>. -    // glibc versions before 2.25 don't handle `O_TMPFILE` correctly. -    #[cfg(all(unix, target_env = "gnu", not(target_os = "hurd")))] -    if oflags.contains(OFlags::TMPFILE) && crate::backend::if_glibc_is_less_than_2_25() { -        return open_via_syscall(path, oflags, mode); -    } - -    // On these platforms, `mode_t` is `u16` and can't be passed directly to a -    // variadic function. -    #[cfg(any( -        apple, -        freebsdlike, -        all(target_os = "android", target_pointer_width = "32") -    ))] -    let mode: c::c_uint = mode.bits().into(); - -    // Otherwise, cast to `mode_t` as that's what `open` is documented to take. -    #[cfg(not(any( -        apple, -        freebsdlike, -        all(target_os = "android", target_pointer_width = "32") -    )))] -    let mode: c::mode_t = mode.bits() as _; - -    unsafe { ret_owned_fd(c::open(c_str(path), bitflags_bits!(oflags), mode)) } -} - -/// Use a direct syscall (via libc) for `openat`. -/// -/// This is only currently necessary as a workaround for old glibc; see below. -#[cfg(all(unix, target_env = "gnu", not(target_os = "hurd")))] -fn openat_via_syscall( -    dirfd: BorrowedFd<'_>, -    path: &CStr, -    oflags: OFlags, -    mode: Mode, -) -> io::Result<OwnedFd> { -    syscall! { -        fn openat( -            base_dirfd: c::c_int, -            pathname: *const c::c_char, -            oflags: c::c_int, -            mode: c::mode_t -        ) via SYS_openat -> c::c_int -    } - -    unsafe { -        ret_owned_fd(openat( -            borrowed_fd(dirfd), -            c_str(path), -            bitflags_bits!(oflags), -            bitflags_bits!(mode), -        )) -    } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn openat( -    dirfd: BorrowedFd<'_>, -    path: &CStr, -    oflags: OFlags, -    mode: Mode, -) -> io::Result<OwnedFd> { -    // Work around <https://sourceware.org/bugzilla/show_bug.cgi?id=17523>. -    // glibc versions before 2.25 don't handle `O_TMPFILE` correctly. -    #[cfg(all(unix, target_env = "gnu", not(target_os = "hurd")))] -    if oflags.contains(OFlags::TMPFILE) && crate::backend::if_glibc_is_less_than_2_25() { -        return openat_via_syscall(dirfd, path, oflags, mode); -    } - -    // On these platforms, `mode_t` is `u16` and can't be passed directly to a -    // variadic function. -    #[cfg(any( -        apple, -        freebsdlike, -        all(target_os = "android", target_pointer_width = "32") -    ))] -    let mode: c::c_uint = mode.bits().into(); - -    // Otherwise, cast to `mode_t` as that's what `open` is documented to take. -    #[cfg(not(any( -        apple, -        freebsdlike, -        all(target_os = "android", target_pointer_width = "32") -    )))] -    let mode: c::mode_t = mode.bits() as _; - -    unsafe { -        ret_owned_fd(c::openat( -            borrowed_fd(dirfd), -            c_str(path), -            bitflags_bits!(oflags), -            mode, -        )) -    } -} - -#[cfg(not(any( -    solarish, -    target_os = "espidf", -    target_os = "haiku", -    target_os = "netbsd", -    target_os = "nto", -    target_os = "redox", -    target_os = "vita", -    target_os = "wasi", -)))] -#[inline] -pub(crate) fn statfs(filename: &CStr) -> io::Result<StatFs> { -    unsafe { -        let mut result = MaybeUninit::<StatFs>::uninit(); -        ret(c::statfs(c_str(filename), result.as_mut_ptr()))?; -        Ok(result.assume_init()) -    } -} - -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -#[inline] -pub(crate) fn statvfs(filename: &CStr) -> io::Result<StatVfs> { -    unsafe { -        let mut result = MaybeUninit::<c::statvfs>::uninit(); -        ret(c::statvfs(c_str(filename), result.as_mut_ptr()))?; -        Ok(libc_statvfs_to_statvfs(result.assume_init())) -    } -} - -#[cfg(feature = "alloc")] -#[inline] -pub(crate) fn readlink(path: &CStr, buf: &mut [u8]) -> io::Result<usize> { -    unsafe { -        ret_usize( -            c::readlink(c_str(path), buf.as_mut_ptr().cast::<c::c_char>(), buf.len()) as isize, -        ) -    } -} - -#[cfg(not(target_os = "redox"))] -#[inline] -pub(crate) fn readlinkat( -    dirfd: BorrowedFd<'_>, -    path: &CStr, -    buf: &mut [MaybeUninit<u8>], -) -> io::Result<usize> { -    unsafe { -        ret_usize(c::readlinkat( -            borrowed_fd(dirfd), -            c_str(path), -            buf.as_mut_ptr().cast::<c::c_char>(), -            buf.len(), -        ) as isize) -    } -} - -pub(crate) fn mkdir(path: &CStr, mode: Mode) -> io::Result<()> { -    unsafe { ret(c::mkdir(c_str(path), mode.bits() as c::mode_t)) } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn mkdirat(dirfd: BorrowedFd<'_>, path: &CStr, mode: Mode) -> io::Result<()> { -    unsafe { -        ret(c::mkdirat( -            borrowed_fd(dirfd), -            c_str(path), -            mode.bits() as c::mode_t, -        )) -    } -} - -#[cfg(linux_kernel)] -pub(crate) fn getdents_uninit( -    fd: BorrowedFd<'_>, -    buf: &mut [MaybeUninit<u8>], -) -> io::Result<usize> { -    syscall! { -        fn getdents64( -            fd: c::c_int, -            dirp: *mut c::c_void, -            count: usize -        ) via SYS_getdents64 -> c::ssize_t -    } -    unsafe { -        ret_usize(getdents64( -            borrowed_fd(fd), -            buf.as_mut_ptr().cast::<c::c_void>(), -            buf.len(), -        )) -    } -} - -pub(crate) fn link(old_path: &CStr, new_path: &CStr) -> io::Result<()> { -    unsafe { ret(c::link(c_str(old_path), c_str(new_path))) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] -pub(crate) fn linkat( -    old_dirfd: BorrowedFd<'_>, -    old_path: &CStr, -    new_dirfd: BorrowedFd<'_>, -    new_path: &CStr, -    flags: AtFlags, -) -> io::Result<()> { -    // macOS <= 10.9 lacks `linkat`. -    #[cfg(target_os = "macos")] -    unsafe { -        weak! { -            fn linkat( -                c::c_int, -                *const c::c_char, -                c::c_int, -                *const c::c_char, -                c::c_int -            ) -> c::c_int -        } -        // If we have `linkat`, use it. -        if let Some(libc_linkat) = linkat.get() { -            return ret(libc_linkat( -                borrowed_fd(old_dirfd), -                c_str(old_path), -                borrowed_fd(new_dirfd), -                c_str(new_path), -                bitflags_bits!(flags), -            )); -        } -        // Otherwise, see if we can emulate the `AT_FDCWD` case. -        if borrowed_fd(old_dirfd) != c::AT_FDCWD || borrowed_fd(new_dirfd) != c::AT_FDCWD { -            return Err(io::Errno::NOSYS); -        } -        if flags.intersects(!AtFlags::SYMLINK_FOLLOW) { -            return Err(io::Errno::INVAL); -        } -        if !flags.is_empty() { -            return Err(io::Errno::OPNOTSUPP); -        } -        ret(c::link(c_str(old_path), c_str(new_path))) -    } - -    #[cfg(not(target_os = "macos"))] -    unsafe { -        ret(c::linkat( -            borrowed_fd(old_dirfd), -            c_str(old_path), -            borrowed_fd(new_dirfd), -            c_str(new_path), -            bitflags_bits!(flags), -        )) -    } -} - -pub(crate) fn rmdir(path: &CStr) -> io::Result<()> { -    unsafe { ret(c::rmdir(c_str(path))) } -} - -pub(crate) fn unlink(path: &CStr) -> io::Result<()> { -    unsafe { ret(c::unlink(c_str(path))) } -} - -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] -pub(crate) fn unlinkat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<()> { -    // macOS <= 10.9 lacks `unlinkat`. -    #[cfg(target_os = "macos")] -    unsafe { -        weak! { -            fn unlinkat( -                c::c_int, -                *const c::c_char, -                c::c_int -            ) -> c::c_int -        } -        // If we have `unlinkat`, use it. -        if let Some(libc_unlinkat) = unlinkat.get() { -            return ret(libc_unlinkat( -                borrowed_fd(dirfd), -                c_str(path), -                bitflags_bits!(flags), -            )); -        } -        // Otherwise, see if we can emulate the `AT_FDCWD` case. -        if borrowed_fd(dirfd) != c::AT_FDCWD { -            return Err(io::Errno::NOSYS); -        } -        if flags.intersects(!AtFlags::REMOVEDIR) { -            return Err(io::Errno::INVAL); -        } -        if flags.contains(AtFlags::REMOVEDIR) { -            ret(c::rmdir(c_str(path))) -        } else { -            ret(c::unlink(c_str(path))) -        } -    } - -    #[cfg(not(target_os = "macos"))] -    unsafe { -        ret(c::unlinkat( -            borrowed_fd(dirfd), -            c_str(path), -            bitflags_bits!(flags), -        )) -    } -} - -pub(crate) fn rename(old_path: &CStr, new_path: &CStr) -> io::Result<()> { -    unsafe { ret(c::rename(c_str(old_path), c_str(new_path))) } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn renameat( -    old_dirfd: BorrowedFd<'_>, -    old_path: &CStr, -    new_dirfd: BorrowedFd<'_>, -    new_path: &CStr, -) -> io::Result<()> { -    // macOS <= 10.9 lacks `renameat`. -    #[cfg(target_os = "macos")] -    unsafe { -        weak! { -            fn renameat( -                c::c_int, -                *const c::c_char, -                c::c_int, -                *const c::c_char -            ) -> c::c_int -        } -        // If we have `renameat`, use it. -        if let Some(libc_renameat) = renameat.get() { -            return ret(libc_renameat( -                borrowed_fd(old_dirfd), -                c_str(old_path), -                borrowed_fd(new_dirfd), -                c_str(new_path), -            )); -        } -        // Otherwise, see if we can emulate the `AT_FDCWD` case. -        if borrowed_fd(old_dirfd) != c::AT_FDCWD || borrowed_fd(new_dirfd) != c::AT_FDCWD { -            return Err(io::Errno::NOSYS); -        } -        ret(c::rename(c_str(old_path), c_str(new_path))) -    } - -    #[cfg(not(target_os = "macos"))] -    unsafe { -        ret(c::renameat( -            borrowed_fd(old_dirfd), -            c_str(old_path), -            borrowed_fd(new_dirfd), -            c_str(new_path), -        )) -    } -} - -#[cfg(all(target_os = "linux", target_env = "gnu"))] -pub(crate) fn renameat2( -    old_dirfd: BorrowedFd<'_>, -    old_path: &CStr, -    new_dirfd: BorrowedFd<'_>, -    new_path: &CStr, -    flags: RenameFlags, -) -> io::Result<()> { -    // `renameat2` wasn't supported in glibc until 2.28. -    weak_or_syscall! { -        fn renameat2( -            olddirfd: c::c_int, -            oldpath: *const c::c_char, -            newdirfd: c::c_int, -            newpath: *const c::c_char, -            flags: c::c_uint -        ) via SYS_renameat2 -> c::c_int -    } - -    unsafe { -        ret(renameat2( -            borrowed_fd(old_dirfd), -            c_str(old_path), -            borrowed_fd(new_dirfd), -            c_str(new_path), -            flags.bits(), -        )) -    } -} - -#[cfg(any( -    target_os = "android", -    all(target_os = "linux", not(target_env = "gnu")), -))] -#[inline] -pub(crate) fn renameat2( -    old_dirfd: BorrowedFd<'_>, -    old_path: &CStr, -    new_dirfd: BorrowedFd<'_>, -    new_path: &CStr, -    flags: RenameFlags, -) -> io::Result<()> { -    // At present, `libc` only has `renameat2` defined for glibc. If we have -    // no flags, we can use plain `renameat`, but otherwise we use `syscall!`. -    // to call `renameat2` ourselves. -    if flags.is_empty() { -        renameat(old_dirfd, old_path, new_dirfd, new_path) -    } else { -        syscall! { -            fn renameat2( -                olddirfd: c::c_int, -                oldpath: *const c::c_char, -                newdirfd: c::c_int, -                newpath: *const c::c_char, -                flags: c::c_uint -            ) via SYS_renameat2 -> c::c_int -        } - -        unsafe { -            ret(renameat2( -                borrowed_fd(old_dirfd), -                c_str(old_path), -                borrowed_fd(new_dirfd), -                c_str(new_path), -                flags.bits(), -            )) -        } -    } -} - -pub(crate) fn symlink(old_path: &CStr, new_path: &CStr) -> io::Result<()> { -    unsafe { ret(c::symlink(c_str(old_path), c_str(new_path))) } -} - -#[cfg(not(target_os = "redox"))] -pub(crate) fn symlinkat( -    old_path: &CStr, -    new_dirfd: BorrowedFd<'_>, -    new_path: &CStr, -) -> io::Result<()> { -    unsafe { -        ret(c::symlinkat( -            c_str(old_path), -            borrowed_fd(new_dirfd), -            c_str(new_path), -        )) -    } -} - -pub(crate) fn stat(path: &CStr) -> io::Result<Stat> { -    // See the comments in `fstat` about using `crate::fs::statx` here. -    #[cfg(all( -        linux_kernel, -        any( -            target_pointer_width = "32", -            target_arch = "mips64", -            target_arch = "mips64r6" -        ) -    ))] -    { -        match crate::fs::statx( -            crate::fs::CWD, -            path, -            AtFlags::empty(), -            StatxFlags::BASIC_STATS, -        ) { -            Ok(x) => statx_to_stat(x), -            Err(io::Errno::NOSYS) => statat_old(crate::fs::CWD, path, AtFlags::empty()), -            Err(err) => Err(err), -        } -    } - -    // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and -    // there's nothing practical we can do. -    #[cfg(not(all( -        linux_kernel, -        any( -            target_pointer_width = "32", -            target_arch = "mips64", -            target_arch = "mips64r6" -        ) -    )))] -    unsafe { -        let mut stat = MaybeUninit::<Stat>::uninit(); -        ret(c::stat(c_str(path), stat.as_mut_ptr()))?; -        Ok(stat.assume_init()) -    } -} - -pub(crate) fn lstat(path: &CStr) -> io::Result<Stat> { -    // See the comments in `fstat` about using `crate::fs::statx` here. -    #[cfg(all( -        linux_kernel, -        any( -            target_pointer_width = "32", -            target_arch = "mips64", -            target_arch = "mips64r6" -        ) -    ))] -    { -        match crate::fs::statx( -            crate::fs::CWD, -            path, -            AtFlags::SYMLINK_NOFOLLOW, -            StatxFlags::BASIC_STATS, -        ) { -            Ok(x) => statx_to_stat(x), -            Err(io::Errno::NOSYS) => statat_old(crate::fs::CWD, path, AtFlags::SYMLINK_NOFOLLOW), -            Err(err) => Err(err), -        } -    } - -    // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and -    // there's nothing practical we can do. -    #[cfg(not(all( -        linux_kernel, -        any( -            target_pointer_width = "32", -            target_arch = "mips64", -            target_arch = "mips64r6" -        ) -    )))] -    unsafe { -        let mut stat = MaybeUninit::<Stat>::uninit(); -        ret(c::lstat(c_str(path), stat.as_mut_ptr()))?; -        Ok(stat.assume_init()) -    } -} - -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] -pub(crate) fn statat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<Stat> { -    // See the comments in `fstat` about using `crate::fs::statx` here. -    #[cfg(all( -        linux_kernel, -        any( -            target_pointer_width = "32", -            target_arch = "mips64", -            target_arch = "mips64r6" -        ) -    ))] -    { -        match crate::fs::statx(dirfd, path, flags, StatxFlags::BASIC_STATS) { -            Ok(x) => statx_to_stat(x), -            Err(io::Errno::NOSYS) => statat_old(dirfd, path, flags), -            Err(err) => Err(err), -        } -    } - -    // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and -    // there's nothing practical we can do. -    #[cfg(not(all( -        linux_kernel, -        any( -            target_pointer_width = "32", -            target_arch = "mips64", -            target_arch = "mips64r6" -        ) -    )))] -    unsafe { -        let mut stat = MaybeUninit::<Stat>::uninit(); -        ret(c::fstatat( -            borrowed_fd(dirfd), -            c_str(path), -            stat.as_mut_ptr(), -            bitflags_bits!(flags), -        ))?; -        Ok(stat.assume_init()) -    } -} - -#[cfg(all( -    linux_kernel, -    any( -        target_pointer_width = "32", -        target_arch = "mips64", -        target_arch = "mips64r6" -    ) -))] -fn statat_old(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::Result<Stat> { -    unsafe { -        let mut result = MaybeUninit::<c::stat64>::uninit(); -        ret(c::fstatat( -            borrowed_fd(dirfd), -            c_str(path), -            result.as_mut_ptr(), -            bitflags_bits!(flags), -        ))?; -        stat64_to_stat(result.assume_init()) -    } -} - -#[cfg(not(any(target_os = "espidf", target_os = "emscripten", target_os = "vita")))] -pub(crate) fn access(path: &CStr, access: Access) -> io::Result<()> { -    unsafe { ret(c::access(c_str(path), access.bits())) } -} - -#[cfg(not(any( -    target_os = "emscripten", -    target_os = "espidf", -    target_os = "redox", -    target_os = "vita" -)))] -pub(crate) fn accessat( -    dirfd: BorrowedFd<'_>, -    path: &CStr, -    access: Access, -    flags: AtFlags, -) -> io::Result<()> { -    // macOS <= 10.9 lacks `faccessat`. -    #[cfg(target_os = "macos")] -    unsafe { -        weak! { -            fn faccessat( -                c::c_int, -                *const c::c_char, -                c::c_int, -                c::c_int -            ) -> c::c_int -        } -        // If we have `faccessat`, use it. -        if let Some(libc_faccessat) = faccessat.get() { -            return ret(libc_faccessat( -                borrowed_fd(dirfd), -                c_str(path), -                bitflags_bits!(access), -                bitflags_bits!(flags), -            )); -        } -        // Otherwise, see if we can emulate the `AT_FDCWD` case. -        if borrowed_fd(dirfd) != c::AT_FDCWD { -            return Err(io::Errno::NOSYS); -        } -        if flags.intersects(!(AtFlags::EACCESS | AtFlags::SYMLINK_NOFOLLOW)) { -            return Err(io::Errno::INVAL); -        } -        if !flags.is_empty() { -            return Err(io::Errno::OPNOTSUPP); -        } -        ret(c::access(c_str(path), bitflags_bits!(access))) -    } - -    #[cfg(not(target_os = "macos"))] -    unsafe { -        ret(c::faccessat( -            borrowed_fd(dirfd), -            c_str(path), -            bitflags_bits!(access), -            bitflags_bits!(flags), -        )) -    } -} - -#[cfg(target_os = "emscripten")] -pub(crate) fn access(_path: &CStr, _access: Access) -> io::Result<()> { -    Ok(()) -} - -#[cfg(target_os = "emscripten")] -pub(crate) fn accessat( -    _dirfd: BorrowedFd<'_>, -    _path: &CStr, -    _access: Access, -    _flags: AtFlags, -) -> io::Result<()> { -    Ok(()) -} - -#[cfg(not(any(target_os = "espidf", target_os = "redox", target_os = "vita")))] -pub(crate) fn utimensat( -    dirfd: BorrowedFd<'_>, -    path: &CStr, -    times: &Timestamps, -    flags: AtFlags, -) -> io::Result<()> { -    // Old 32-bit version: libc has `utimensat` but it is not y2038 safe by -    // default. But there may be a `__utimensat16` we can use. -    #[cfg(fix_y2038)] -    { -        #[cfg(target_env = "gnu")] -        if let Some(libc_utimensat) = __utimensat64.get() { -            let libc_times: [LibcTimespec; 2] = [ -                times.last_access.clone().into(), -                times.last_modification.clone().into(), -            ]; - -            unsafe { -                return ret(libc_utimensat( -                    borrowed_fd(dirfd), -                    c_str(path), -                    libc_times.as_ptr(), -                    bitflags_bits!(flags), -                )); -            } -        } - -        utimensat_old(dirfd, path, times, flags) -    } - -    // Main version: libc is y2038 safe and has `utimensat`. Or, the platform -    // is not y2038 safe and there's nothing practical we can do. -    #[cfg(not(any(apple, fix_y2038)))] -    unsafe { -        use crate::utils::as_ptr; - -        ret(c::utimensat( -            borrowed_fd(dirfd), -            c_str(path), -            as_ptr(times).cast(), -            bitflags_bits!(flags), -        )) -    } - -    // Apple version: `utimensat` was introduced in macOS 10.13. -    #[cfg(apple)] -    unsafe { -        use crate::utils::as_ptr; - -        // ABI details -        weak! { -            fn utimensat( -                c::c_int, -                *const c::c_char, -                *const c::timespec, -                c::c_int -            ) -> c::c_int -        } -        extern "C" { -            fn setattrlist( -                path: *const c::c_char, -                attr_list: *const Attrlist, -                attr_buf: *const c::c_void, -                attr_buf_size: c::size_t, -                options: c::c_ulong, -            ) -> c::c_int; -        } -        const FSOPT_NOFOLLOW: c::c_ulong = 0x0000_0001; - -        // If we have `utimensat`, use it. -        if let Some(have_utimensat) = utimensat.get() { -            return ret(have_utimensat( -                borrowed_fd(dirfd), -                c_str(path), -                as_ptr(times).cast(), -                bitflags_bits!(flags), -            )); -        } - -        // `setattrlistat` was introduced in 10.13 along with `utimensat`, so -        // if we don't have `utimensat`, we don't have `setattrlistat` either. -        // Emulate it using `fork`, and `fchdir` and [`setattrlist`]. -        // -        // [`setattrlist`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setattrlist.2.html -        match c::fork() { -            -1 => Err(io::Errno::IO), -            0 => { -                if c::fchdir(borrowed_fd(dirfd)) != 0 { -                    let code = match libc_errno::errno().0 { -                        c::EACCES => 2, -                        c::ENOTDIR => 3, -                        _ => 1, -                    }; -                    c::_exit(code); -                } - -                let mut flags_arg = 0; -                if flags.contains(AtFlags::SYMLINK_NOFOLLOW) { -                    flags_arg |= FSOPT_NOFOLLOW; -                } - -                let (attrbuf_size, times, attrs) = times_to_attrlist(times); - -                if setattrlist( -                    c_str(path), -                    &attrs, -                    as_ptr(×).cast(), -                    attrbuf_size, -                    flags_arg, -                ) != 0 -                { -                    // Translate expected `errno` codes into ad-hoc integer -                    // values suitable for exit statuses. -                    let code = match libc_errno::errno().0 { -                        c::EACCES => 2, -                        c::ENOTDIR => 3, -                        c::EPERM => 4, -                        c::EROFS => 5, -                        c::ELOOP => 6, -                        c::ENOENT => 7, -                        c::ENAMETOOLONG => 8, -                        c::EINVAL => 9, -                        c::ESRCH => 10, -                        c::ENOTSUP => 11, -                        _ => 1, -                    }; -                    c::_exit(code); -                } - -                c::_exit(0); -            } -            child_pid => { -                let mut wstatus = 0; -                let _ = ret_c_int(c::waitpid(child_pid, &mut wstatus, 0))?; -                if c::WIFEXITED(wstatus) { -                    // Translate our ad-hoc exit statuses back to `errno` -                    // codes. -                    match c::WEXITSTATUS(wstatus) { -                        0 => Ok(()), -                        2 => Err(io::Errno::ACCESS), -                        3 => Err(io::Errno::NOTDIR), -                        4 => Err(io::Errno::PERM), -                        5 => Err(io::Errno::ROFS), -                        6 => Err(io::Errno::LOOP), -                        7 => Err(io::Errno::NOENT), -                        8 => Err(io::Errno::NAMETOOLONG), -                        9 => Err(io::Errno::INVAL), -                        10 => Err(io::Errno::SRCH), -                        11 => Err(io::Errno::NOTSUP), -                        _ => Err(io::Errno::IO), -                    } -                } else { -                    Err(io::Errno::IO) -                } -            } -        } -    } -} - -#[cfg(fix_y2038)] -fn utimensat_old( -    dirfd: BorrowedFd<'_>, -    path: &CStr, -    times: &Timestamps, -    flags: AtFlags, -) -> io::Result<()> { -    let old_times = [ -        c::timespec { -            tv_sec: times -                .last_access -                .tv_sec -                .try_into() -                .map_err(|_| io::Errno::OVERFLOW)?, -            tv_nsec: times -                .last_access -                .tv_nsec -                .try_into() -                .map_err(|_| io::Errno::OVERFLOW)?, -        }, -        c::timespec { -            tv_sec: times -                .last_modification -                .tv_sec -                .try_into() -                .map_err(|_| io::Errno::OVERFLOW)?, -            tv_nsec: times -                .last_modification -                .tv_nsec -                .try_into() -                .map_err(|_| io::Errno::OVERFLOW)?, -        }, -    ]; -    unsafe { -        ret(c::utimensat( -            borrowed_fd(dirfd), -            c_str(path), -            old_times.as_ptr(), -            bitflags_bits!(flags), -        )) -    } -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn chmod(path: &CStr, mode: Mode) -> io::Result<()> { -    unsafe { ret(c::chmod(c_str(path), mode.bits() as c::mode_t)) } -} - -#[cfg(not(any( -    linux_kernel, -    target_os = "espidf", -    target_os = "redox", -    target_os = "wasi" -)))] -pub(crate) fn chmodat( -    dirfd: BorrowedFd<'_>, -    path: &CStr, -    mode: Mode, -    flags: AtFlags, -) -> io::Result<()> { -    unsafe { -        ret(c::fchmodat( -            borrowed_fd(dirfd), -            c_str(path), -            mode.bits() as c::mode_t, -            bitflags_bits!(flags), -        )) -    } -} - -#[cfg(linux_kernel)] -pub(crate) fn chmodat( -    dirfd: BorrowedFd<'_>, -    path: &CStr, -    mode: Mode, -    flags: AtFlags, -) -> io::Result<()> { -    // Linux's `fchmodat` does not have a flags argument. -    // -    // Use `c::syscall` rather than `c::fchmodat` because some libc -    // implementations, such as musl, add extra logic to `fchmod` to emulate -    // support for `AT_SYMLINK_NOFOLLOW`, which uses `/proc` outside our -    // control. -    syscall! { -        fn fchmodat( -            base_dirfd: c::c_int, -            pathname: *const c::c_char, -            mode: c::mode_t -        ) via SYS_fchmodat -> c::c_int -    } -    if flags == AtFlags::SYMLINK_NOFOLLOW { -        return Err(io::Errno::OPNOTSUPP); -    } -    if !flags.is_empty() { -        return Err(io::Errno::INVAL); -    } -    unsafe { -        ret(fchmodat( -            borrowed_fd(dirfd), -            c_str(path), -            mode.bits() as c::mode_t, -        )) -    } -} - -#[cfg(apple)] -pub(crate) fn fclonefileat( -    srcfd: BorrowedFd<'_>, -    dst_dirfd: BorrowedFd<'_>, -    dst: &CStr, -    flags: CloneFlags, -) -> io::Result<()> { -    syscall! { -        fn fclonefileat( -            srcfd: BorrowedFd<'_>, -            dst_dirfd: BorrowedFd<'_>, -            dst: *const c::c_char, -            flags: c::c_int -        ) via SYS_fclonefileat -> c::c_int -    } - -    unsafe { -        ret(fclonefileat( -            srcfd, -            dst_dirfd, -            c_str(dst), -            bitflags_bits!(flags), -        )) -    } -} - -#[cfg(not(any(target_os = "espidf", target_os = "redox", target_os = "wasi")))] -pub(crate) fn chownat( -    dirfd: BorrowedFd<'_>, -    path: &CStr, -    owner: Option<Uid>, -    group: Option<Gid>, -    flags: AtFlags, -) -> io::Result<()> { -    unsafe { -        let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); -        ret(c::fchownat( -            borrowed_fd(dirfd), -            c_str(path), -            ow, -            gr, -            bitflags_bits!(flags), -        )) -    } -} - -#[cfg(not(any( -    apple, -    target_os = "espidf", -    target_os = "redox", -    target_os = "vita", -    target_os = "wasi" -)))] -pub(crate) fn mknodat( -    dirfd: BorrowedFd<'_>, -    path: &CStr, -    file_type: FileType, -    mode: Mode, -    dev: Dev, -) -> io::Result<()> { -    unsafe { -        ret(c::mknodat( -            borrowed_fd(dirfd), -            c_str(path), -            (mode.bits() | file_type.as_raw_mode()) as c::mode_t, -            dev.try_into().map_err(|_e| io::Errno::PERM)?, -        )) -    } -} - -#[cfg(linux_kernel)] -pub(crate) fn copy_file_range( -    fd_in: BorrowedFd<'_>, -    off_in: Option<&mut u64>, -    fd_out: BorrowedFd<'_>, -    off_out: Option<&mut u64>, -    len: usize, -) -> io::Result<usize> { -    syscall! { -        fn copy_file_range( -            fd_in: c::c_int, -            off_in: *mut c::loff_t, -            fd_out: c::c_int, -            off_out: *mut c::loff_t, -            len: usize, -            flags: c::c_uint -        ) via SYS_copy_file_range -> c::ssize_t -    } - -    let mut off_in_val: c::loff_t = 0; -    let mut off_out_val: c::loff_t = 0; -    // Silently cast; we'll get `EINVAL` if the value is negative. -    let off_in_ptr = if let Some(off_in) = &off_in { -        off_in_val = **off_in as i64; -        &mut off_in_val -    } else { -        null_mut() -    }; -    let off_out_ptr = if let Some(off_out) = &off_out { -        off_out_val = **off_out as i64; -        &mut off_out_val -    } else { -        null_mut() -    }; -    let copied = unsafe { -        ret_usize(copy_file_range( -            borrowed_fd(fd_in), -            off_in_ptr, -            borrowed_fd(fd_out), -            off_out_ptr, -            len, -            0, // no flags are defined yet -        ))? -    }; -    if let Some(off_in) = off_in { -        *off_in = off_in_val as u64; -    } -    if let Some(off_out) = off_out { -        *off_out = off_out_val as u64; -    } -    Ok(copied) -} - -#[cfg(not(any( -    apple, -    netbsdlike, -    solarish, -    target_os = "dragonfly", -    target_os = "espidf", -    target_os = "haiku", -    target_os = "redox", -    target_os = "vita", -)))] -pub(crate) fn fadvise(fd: BorrowedFd<'_>, offset: u64, len: u64, advice: Advice) -> io::Result<()> { -    let offset = offset as i64; -    let len = len as i64; - -    // FreeBSD returns `EINVAL` on invalid offsets; emulate the POSIX behavior. -    #[cfg(target_os = "freebsd")] -    let offset = if (offset as i64) < 0 { -        i64::MAX -    } else { -        offset -    }; - -    // FreeBSD returns `EINVAL` on overflow; emulate the POSIX behavior. -    #[cfg(target_os = "freebsd")] -    let len = if len > 0 && offset.checked_add(len).is_none() { -        i64::MAX - offset -    } else { -        len -    }; - -    let err = unsafe { c::posix_fadvise(borrowed_fd(fd), offset, len, advice as c::c_int) }; - -    // `posix_fadvise` returns its error status rather than using `errno`. -    if err == 0 { -        Ok(()) -    } else { -        Err(io::Errno(err)) -    } -} - -pub(crate) fn fcntl_getfl(fd: BorrowedFd<'_>) -> io::Result<OFlags> { -    let flags = unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETFL))? }; -    Ok(OFlags::from_bits_retain(bitcast!(flags))) -} - -pub(crate) fn fcntl_setfl(fd: BorrowedFd<'_>, flags: OFlags) -> io::Result<()> { -    unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_SETFL, flags.bits())) } -} - -#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] -pub(crate) fn fcntl_get_seals(fd: BorrowedFd<'_>) -> io::Result<SealFlags> { -    let flags = unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GET_SEALS))? }; -    Ok(SealFlags::from_bits_retain(bitcast!(flags))) -} - -#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] -pub(crate) fn fcntl_add_seals(fd: BorrowedFd<'_>, seals: SealFlags) -> io::Result<()> { -    unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_ADD_SEALS, seals.bits())) } -} - -#[cfg(not(any( -    target_os = "emscripten", -    target_os = "espidf", -    target_os = "fuchsia", -    target_os = "redox", -    target_os = "vita", -    target_os = "wasi" -)))] -#[inline] -pub(crate) fn fcntl_lock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result<()> { -    use c::{flock, F_RDLCK, F_SETLK, F_SETLKW, F_UNLCK, F_WRLCK, SEEK_SET}; - -    let (cmd, l_type) = match operation { -        FlockOperation::LockShared => (F_SETLKW, F_RDLCK), -        FlockOperation::LockExclusive => (F_SETLKW, F_WRLCK), -        FlockOperation::Unlock => (F_SETLKW, F_UNLCK), -        FlockOperation::NonBlockingLockShared => (F_SETLK, F_RDLCK), -        FlockOperation::NonBlockingLockExclusive => (F_SETLK, F_WRLCK), -        FlockOperation::NonBlockingUnlock => (F_SETLK, F_UNLCK), -    }; - -    unsafe { -        let mut lock: flock = core::mem::zeroed(); -        lock.l_type = l_type as _; - -        // When `l_len` is zero, this locks all the bytes from -        // `l_whence`/`l_start` to the end of the file, even as the -        // file grows dynamically. -        lock.l_whence = SEEK_SET as _; -        lock.l_start = 0; -        lock.l_len = 0; - -        ret(c::fcntl(borrowed_fd(fd), cmd, &lock)) -    } -} - -pub(crate) fn seek(fd: BorrowedFd<'_>, pos: SeekFrom) -> io::Result<u64> { -    let (whence, offset) = match pos { -        SeekFrom::Start(pos) => { -            let pos: u64 = pos; -            // Silently cast; we'll get `EINVAL` if the value is negative. -            (c::SEEK_SET, pos as i64) -        } -        SeekFrom::End(offset) => (c::SEEK_END, offset), -        SeekFrom::Current(offset) => (c::SEEK_CUR, offset), -        #[cfg(any(apple, freebsdlike, linux_kernel, solarish))] -        SeekFrom::Data(offset) => (c::SEEK_DATA, offset), -        #[cfg(any(apple, freebsdlike, linux_kernel, solarish))] -        SeekFrom::Hole(offset) => (c::SEEK_HOLE, offset), -    }; - -    // ESP-IDF and Vita don't support 64-bit offsets. -    #[cfg(any(target_os = "espidf", target_os = "vita"))] -    let offset: i32 = offset.try_into().map_err(|_| io::Errno::OVERFLOW)?; - -    let offset = unsafe { ret_off_t(c::lseek(borrowed_fd(fd), offset, whence))? }; -    Ok(offset as u64) -} - -pub(crate) fn tell(fd: BorrowedFd<'_>) -> io::Result<u64> { -    let offset = unsafe { ret_off_t(c::lseek(borrowed_fd(fd), 0, c::SEEK_CUR))? }; -    Ok(offset as u64) -} - -#[cfg(not(any(linux_kernel, target_os = "wasi")))] -pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> { -    unsafe { ret(c::fchmod(borrowed_fd(fd), bitflags_bits!(mode))) } -} - -#[cfg(linux_kernel)] -pub(crate) fn fchmod(fd: BorrowedFd<'_>, mode: Mode) -> io::Result<()> { -    // Use `c::syscall` rather than `c::fchmod` because some libc -    // implementations, such as musl, add extra logic to `fchmod` to emulate -    // support for `O_PATH`, which uses `/proc` outside our control and -    // interferes with our own use of `O_PATH`. -    syscall! { -        fn fchmod( -            fd: c::c_int, -            mode: c::mode_t -        ) via SYS_fchmod -> c::c_int -    } -    unsafe { ret(fchmod(borrowed_fd(fd), mode.bits() as c::mode_t)) } -} - -#[cfg(not(target_os = "wasi"))] -pub(crate) fn chown(path: &CStr, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> { -    unsafe { -        let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); -        ret(c::chown(c_str(path), ow, gr)) -    } -} - -#[cfg(linux_kernel)] -pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> { -    // Use `c::syscall` rather than `c::fchown` because some libc -    // implementations, such as musl, add extra logic to `fchown` to emulate -    // support for `O_PATH`, which uses `/proc` outside our control and -    // interferes with our own use of `O_PATH`. -    syscall! { -        fn fchown( -            fd: c::c_int, -            owner: c::uid_t, -            group: c::gid_t -        ) via SYS_fchown -> c::c_int -    } -    unsafe { -        let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); -        ret(fchown(borrowed_fd(fd), ow, gr)) -    } -} - -#[cfg(not(any(linux_kernel, target_os = "wasi")))] -pub(crate) fn fchown(fd: BorrowedFd<'_>, owner: Option<Uid>, group: Option<Gid>) -> io::Result<()> { -    unsafe { -        let (ow, gr) = crate::ugid::translate_fchown_args(owner, group); -        ret(c::fchown(borrowed_fd(fd), ow, gr)) -    } -} - -#[cfg(not(any( -    target_os = "espidf", -    target_os = "solaris", -    target_os = "vita", -    target_os = "wasi" -)))] -pub(crate) fn flock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result<()> { -    unsafe { ret(c::flock(borrowed_fd(fd), operation as c::c_int)) } -} - -#[cfg(linux_kernel)] -pub(crate) fn syncfs(fd: BorrowedFd<'_>) -> io::Result<()> { -    // Some versions of Android libc lack a `syncfs` function. -    #[cfg(target_os = "android")] -    syscall! { -        fn syncfs(fd: c::c_int) via SYS_syncfs -> c::c_int -    } - -    // `syncfs` was added to glibc in 2.20. -    #[cfg(not(target_os = "android"))] -    weak_or_syscall! { -        fn syncfs(fd: c::c_int) via SYS_syncfs -> c::c_int -    } - -    unsafe { ret(syncfs(borrowed_fd(fd))) } -} - -#[cfg(not(any( -    target_os = "espidf", -    target_os = "redox", -    target_os = "vita", -    target_os = "wasi" -)))] -pub(crate) fn sync() { -    unsafe { c::sync() } -} - -pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result<Stat> { -    // 32-bit and mips64 Linux: `struct stat64` is not y2038 compatible; use -    // `statx`. -    // -    // And, some old platforms don't support `statx`, and some fail with a -    // confusing error code, so we call `crate::fs::statx` to handle that. If -    // `statx` isn't available, fall back to the buggy system call. -    #[cfg(all( -        linux_kernel, -        any( -            target_pointer_width = "32", -            target_arch = "mips64", -            target_arch = "mips64r6" -        ) -    ))] -    { -        match crate::fs::statx(fd, cstr!(""), AtFlags::EMPTY_PATH, StatxFlags::BASIC_STATS) { -            Ok(x) => statx_to_stat(x), -            Err(io::Errno::NOSYS) => fstat_old(fd), -            Err(err) => Err(err), -        } -    } - -    // Main version: libc is y2038 safe. Or, the platform is not y2038 safe and -    // there's nothing practical we can do. -    #[cfg(not(all( -        linux_kernel, -        any( -            target_pointer_width = "32", -            target_arch = "mips64", -            target_arch = "mips64r6" -        ) -    )))] -    unsafe { -        let mut stat = MaybeUninit::<Stat>::uninit(); -        ret(c::fstat(borrowed_fd(fd), stat.as_mut_ptr()))?; -        Ok(stat.assume_init()) -    } -} - -#[cfg(all( -    linux_kernel, -    any( -        target_pointer_width = "32", -        target_arch = "mips64", -        target_arch = "mips64r6" -    ) -))] -fn fstat_old(fd: BorrowedFd<'_>) -> io::Result<Stat> { -    unsafe { -        let mut result = MaybeUninit::<c::stat64>::uninit(); -        ret(c::fstat(borrowed_fd(fd), result.as_mut_ptr()))?; -        stat64_to_stat(result.assume_init()) -    } -} - -#[cfg(not(any( -    solarish, -    target_os = "espidf", -    target_os = "haiku", -    target_os = "netbsd", -    target_os = "nto", -    target_os = "redox", -    target_os = "vita", -    target_os = "wasi", -)))] -pub(crate) fn fstatfs(fd: BorrowedFd<'_>) -> io::Result<StatFs> { -    let mut statfs = MaybeUninit::<StatFs>::uninit(); -    unsafe { -        ret(c::fstatfs(borrowed_fd(fd), statfs.as_mut_ptr()))?; -        Ok(statfs.assume_init()) -    } -} - -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -pub(crate) fn fstatvfs(fd: BorrowedFd<'_>) -> io::Result<StatVfs> { -    let mut statvfs = MaybeUninit::<c::statvfs>::uninit(); -    unsafe { -        ret(c::fstatvfs(borrowed_fd(fd), statvfs.as_mut_ptr()))?; -        Ok(libc_statvfs_to_statvfs(statvfs.assume_init())) -    } -} - -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -fn libc_statvfs_to_statvfs(from: c::statvfs) -> StatVfs { -    StatVfs { -        f_bsize: from.f_bsize as u64, -        f_frsize: from.f_frsize as u64, -        f_blocks: from.f_blocks as u64, -        f_bfree: from.f_bfree as u64, -        f_bavail: from.f_bavail as u64, -        f_files: from.f_files as u64, -        f_ffree: from.f_ffree as u64, -        f_favail: from.f_ffree as u64, -        #[cfg(not(target_os = "aix"))] -        f_fsid: from.f_fsid as u64, -        #[cfg(target_os = "aix")] -        f_fsid: ((from.f_fsid.val[0] as u64) << 32) | from.f_fsid.val[1], -        f_flag: StatVfsMountFlags::from_bits_retain(from.f_flag as u64), -        f_namemax: from.f_namemax as u64, -    } -} - -#[cfg(not(any(target_os = "espidf", target_os = "vita")))] -pub(crate) fn futimens(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { -    // Old 32-bit version: libc has `futimens` but it is not y2038 safe by -    // default. But there may be a `__futimens64` we can use. -    #[cfg(fix_y2038)] -    { -        #[cfg(target_env = "gnu")] -        if let Some(libc_futimens) = __futimens64.get() { -            let libc_times: [LibcTimespec; 2] = [ -                times.last_access.clone().into(), -                times.last_modification.clone().into(), -            ]; - -            unsafe { -                return ret(libc_futimens(borrowed_fd(fd), libc_times.as_ptr())); -            } -        } - -        futimens_old(fd, times) -    } - -    // Main version: libc is y2038 safe and has `futimens`. Or, the platform -    // is not y2038 safe and there's nothing practical we can do. -    #[cfg(not(any(apple, fix_y2038)))] -    unsafe { -        use crate::utils::as_ptr; - -        ret(c::futimens(borrowed_fd(fd), as_ptr(times).cast())) -    } - -    // Apple version: `futimens` was introduced in macOS 10.13. -    #[cfg(apple)] -    unsafe { -        use crate::utils::as_ptr; - -        // ABI details. -        weak! { -            fn futimens(c::c_int, *const c::timespec) -> c::c_int -        } -        extern "C" { -            fn fsetattrlist( -                fd: c::c_int, -                attr_list: *const Attrlist, -                attr_buf: *const c::c_void, -                attr_buf_size: c::size_t, -                options: c::c_ulong, -            ) -> c::c_int; -        } - -        // If we have `futimens`, use it. -        if let Some(have_futimens) = futimens.get() { -            return ret(have_futimens(borrowed_fd(fd), as_ptr(times).cast())); -        } - -        // Otherwise use `fsetattrlist`. -        let (attrbuf_size, times, attrs) = times_to_attrlist(times); - -        ret(fsetattrlist( -            borrowed_fd(fd), -            &attrs, -            as_ptr(×).cast(), -            attrbuf_size, -            0, -        )) -    } -} - -#[cfg(fix_y2038)] -fn futimens_old(fd: BorrowedFd<'_>, times: &Timestamps) -> io::Result<()> { -    let old_times = [ -        c::timespec { -            tv_sec: times -                .last_access -                .tv_sec -                .try_into() -                .map_err(|_| io::Errno::OVERFLOW)?, -            tv_nsec: times -                .last_access -                .tv_nsec -                .try_into() -                .map_err(|_| io::Errno::OVERFLOW)?, -        }, -        c::timespec { -            tv_sec: times -                .last_modification -                .tv_sec -                .try_into() -                .map_err(|_| io::Errno::OVERFLOW)?, -            tv_nsec: times -                .last_modification -                .tv_nsec -                .try_into() -                .map_err(|_| io::Errno::OVERFLOW)?, -        }, -    ]; - -    unsafe { ret(c::futimens(borrowed_fd(fd), old_times.as_ptr())) } -} - -#[cfg(not(any( -    apple, -    netbsdlike, -    solarish, -    target_os = "aix", -    target_os = "dragonfly", -    target_os = "espidf", -    target_os = "nto", -    target_os = "redox", -    target_os = "vita", -)))] -pub(crate) fn fallocate( -    fd: BorrowedFd<'_>, -    mode: FallocateFlags, -    offset: u64, -    len: u64, -) -> io::Result<()> { -    // Silently cast; we'll get `EINVAL` if the value is negative. -    let offset = offset as i64; -    let len = len as i64; - -    #[cfg(any(linux_kernel, target_os = "fuchsia"))] -    unsafe { -        ret(c::fallocate( -            borrowed_fd(fd), -            bitflags_bits!(mode), -            offset, -            len, -        )) -    } - -    #[cfg(not(any(linux_kernel, target_os = "fuchsia")))] -    { -        assert!(mode.is_empty()); -        let err = unsafe { c::posix_fallocate(borrowed_fd(fd), offset, len) }; - -        // `posix_fallocate` returns its error status rather than using -        // `errno`. -        if err == 0 { -            Ok(()) -        } else { -            Err(io::Errno(err)) -        } -    } -} - -#[cfg(apple)] -pub(crate) fn fallocate( -    fd: BorrowedFd<'_>, -    mode: FallocateFlags, -    offset: u64, -    len: u64, -) -> io::Result<()> { -    let offset: i64 = offset.try_into().map_err(|_e| io::Errno::INVAL)?; -    let len = len as i64; - -    assert!(mode.is_empty()); - -    let new_len = offset.checked_add(len).ok_or(io::Errno::FBIG)?; -    let mut store = c::fstore_t { -        fst_flags: c::F_ALLOCATECONTIG, -        fst_posmode: c::F_PEOFPOSMODE, -        fst_offset: 0, -        fst_length: new_len, -        fst_bytesalloc: 0, -    }; -    unsafe { -        if c::fcntl(borrowed_fd(fd), c::F_PREALLOCATE, &store) == -1 { -            // Unable to allocate contiguous disk space; attempt to allocate -            // non-contiguously. -            store.fst_flags = c::F_ALLOCATEALL; -            let _ = ret_c_int(c::fcntl(borrowed_fd(fd), c::F_PREALLOCATE, &store))?; -        } -        ret(c::ftruncate(borrowed_fd(fd), new_len)) -    } -} - -pub(crate) fn fsync(fd: BorrowedFd<'_>) -> io::Result<()> { -    unsafe { ret(c::fsync(borrowed_fd(fd))) } -} - -#[cfg(not(any( -    apple, -    target_os = "dragonfly", -    target_os = "espidf", -    target_os = "haiku", -    target_os = "redox", -    target_os = "vita", -)))] -pub(crate) fn fdatasync(fd: BorrowedFd<'_>) -> io::Result<()> { -    unsafe { ret(c::fdatasync(borrowed_fd(fd))) } -} - -pub(crate) fn ftruncate(fd: BorrowedFd<'_>, length: u64) -> io::Result<()> { -    let length = length.try_into().map_err(|_overflow_err| io::Errno::FBIG)?; -    unsafe { ret(c::ftruncate(borrowed_fd(fd), length)) } -} - -#[cfg(any(linux_kernel, target_os = "freebsd"))] -pub(crate) fn memfd_create(name: &CStr, flags: MemfdFlags) -> io::Result<OwnedFd> { -    #[cfg(target_os = "freebsd")] -    weakcall! { -        fn memfd_create( -            name: *const c::c_char, -            flags: c::c_uint -        ) -> c::c_int -    } - -    #[cfg(linux_kernel)] -    weak_or_syscall! { -        fn memfd_create( -            name: *const c::c_char, -            flags: c::c_uint -        ) via SYS_memfd_create -> c::c_int -    } - -    unsafe { ret_owned_fd(memfd_create(c_str(name), bitflags_bits!(flags))) } -} - -#[cfg(linux_kernel)] -pub(crate) fn openat2( -    dirfd: BorrowedFd<'_>, -    path: &CStr, -    oflags: OFlags, -    mode: Mode, -    resolve: ResolveFlags, -) -> io::Result<OwnedFd> { -    use linux_raw_sys::general::open_how; - -    syscall! { -        fn openat2( -            base_dirfd: c::c_int, -            pathname: *const c::c_char, -            how: *mut open_how, -            size: usize -        ) via SYS_OPENAT2 -> c::c_int -    } - -    let oflags = oflags.bits(); -    let mut open_how = open_how { -        flags: u64::from(oflags), -        mode: u64::from(mode.bits()), -        resolve: resolve.bits(), -    }; - -    unsafe { -        ret_owned_fd(openat2( -            borrowed_fd(dirfd), -            c_str(path), -            &mut open_how, -            size_of::<open_how>(), -        )) -    } -} -#[cfg(all(linux_kernel, target_pointer_width = "32"))] -const SYS_OPENAT2: i32 = 437; -#[cfg(all(linux_kernel, target_pointer_width = "64"))] -const SYS_OPENAT2: i64 = 437; - -#[cfg(target_os = "linux")] -pub(crate) fn sendfile( -    out_fd: BorrowedFd<'_>, -    in_fd: BorrowedFd<'_>, -    offset: Option<&mut u64>, -    count: usize, -) -> io::Result<usize> { -    unsafe { -        ret_usize(c::sendfile64( -            borrowed_fd(out_fd), -            borrowed_fd(in_fd), -            offset.map_or(null_mut(), crate::utils::as_mut_ptr).cast(), -            count, -        )) -    } -} - -/// Convert from a Linux `statx` value to rustix's `Stat`. -#[cfg(all(linux_kernel, target_pointer_width = "32"))] -fn statx_to_stat(x: crate::fs::Statx) -> io::Result<Stat> { -    Ok(Stat { -        st_dev: crate::fs::makedev(x.stx_dev_major, x.stx_dev_minor).into(), -        st_mode: x.stx_mode.into(), -        st_nlink: x.stx_nlink.into(), -        st_uid: x.stx_uid.into(), -        st_gid: x.stx_gid.into(), -        st_rdev: crate::fs::makedev(x.stx_rdev_major, x.stx_rdev_minor).into(), -        st_size: x.stx_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, -        st_blksize: x.stx_blksize.into(), -        st_blocks: x.stx_blocks.into(), -        st_atime: x -            .stx_atime -            .tv_sec -            .try_into() -            .map_err(|_| io::Errno::OVERFLOW)?, -        st_atime_nsec: x.stx_atime.tv_nsec as _, -        st_mtime: x -            .stx_mtime -            .tv_sec -            .try_into() -            .map_err(|_| io::Errno::OVERFLOW)?, -        st_mtime_nsec: x.stx_mtime.tv_nsec as _, -        st_ctime: x -            .stx_ctime -            .tv_sec -            .try_into() -            .map_err(|_| io::Errno::OVERFLOW)?, -        st_ctime_nsec: x.stx_ctime.tv_nsec as _, -        st_ino: x.stx_ino.into(), -    }) -} - -/// Convert from a Linux `statx` value to rustix's `Stat`. -/// -/// mips64' `struct stat64` in libc has private fields, and `stx_blocks` -#[cfg(all(linux_kernel, any(target_arch = "mips64", target_arch = "mips64r6")))] -fn statx_to_stat(x: crate::fs::Statx) -> io::Result<Stat> { -    let mut result: Stat = unsafe { core::mem::zeroed() }; - -    result.st_dev = crate::fs::makedev(x.stx_dev_major, x.stx_dev_minor); -    result.st_mode = x.stx_mode.into(); -    result.st_nlink = x.stx_nlink.into(); -    result.st_uid = x.stx_uid.into(); -    result.st_gid = x.stx_gid.into(); -    result.st_rdev = crate::fs::makedev(x.stx_rdev_major, x.stx_rdev_minor); -    result.st_size = x.stx_size.try_into().map_err(|_| io::Errno::OVERFLOW)?; -    result.st_blksize = x.stx_blksize.into(); -    result.st_blocks = x.stx_blocks.try_into().map_err(|_e| io::Errno::OVERFLOW)?; -    result.st_atime = x -        .stx_atime -        .tv_sec -        .try_into() -        .map_err(|_| io::Errno::OVERFLOW)?; -    result.st_atime_nsec = x.stx_atime.tv_nsec as _; -    result.st_mtime = x -        .stx_mtime -        .tv_sec -        .try_into() -        .map_err(|_| io::Errno::OVERFLOW)?; -    result.st_mtime_nsec = x.stx_mtime.tv_nsec as _; -    result.st_ctime = x -        .stx_ctime -        .tv_sec -        .try_into() -        .map_err(|_| io::Errno::OVERFLOW)?; -    result.st_ctime_nsec = x.stx_ctime.tv_nsec as _; -    result.st_ino = x.stx_ino.into(); - -    Ok(result) -} - -/// Convert from a Linux `stat64` value to rustix's `Stat`. -#[cfg(all(linux_kernel, target_pointer_width = "32"))] -fn stat64_to_stat(s64: c::stat64) -> io::Result<Stat> { -    Ok(Stat { -        st_dev: s64.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?, -        st_mode: s64.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?, -        st_nlink: s64.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?, -        st_uid: s64.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?, -        st_gid: s64.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?, -        st_rdev: s64.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?, -        st_size: s64.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?, -        st_blksize: s64.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?, -        st_blocks: s64.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?, -        st_atime: s64.st_atime.try_into().map_err(|_| io::Errno::OVERFLOW)?, -        st_atime_nsec: s64 -            .st_atime_nsec -            .try_into() -            .map_err(|_| io::Errno::OVERFLOW)?, -        st_mtime: s64.st_mtime.try_into().map_err(|_| io::Errno::OVERFLOW)?, -        st_mtime_nsec: s64 -            .st_mtime_nsec -            .try_into() -            .map_err(|_| io::Errno::OVERFLOW)?, -        st_ctime: s64.st_ctime.try_into().map_err(|_| io::Errno::OVERFLOW)?, -        st_ctime_nsec: s64 -            .st_ctime_nsec -            .try_into() -            .map_err(|_| io::Errno::OVERFLOW)?, -        st_ino: s64.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?, -    }) -} - -/// Convert from a Linux `stat64` value to rustix's `Stat`. -/// -/// mips64' `struct stat64` in libc has private fields, and `st_blocks` has -/// type `i64`. -#[cfg(all(linux_kernel, any(target_arch = "mips64", target_arch = "mips64r6")))] -fn stat64_to_stat(s64: c::stat64) -> io::Result<Stat> { -    let mut result: Stat = unsafe { core::mem::zeroed() }; - -    result.st_dev = s64.st_dev.try_into().map_err(|_| io::Errno::OVERFLOW)?; -    result.st_mode = s64.st_mode.try_into().map_err(|_| io::Errno::OVERFLOW)?; -    result.st_nlink = s64.st_nlink.try_into().map_err(|_| io::Errno::OVERFLOW)?; -    result.st_uid = s64.st_uid.try_into().map_err(|_| io::Errno::OVERFLOW)?; -    result.st_gid = s64.st_gid.try_into().map_err(|_| io::Errno::OVERFLOW)?; -    result.st_rdev = s64.st_rdev.try_into().map_err(|_| io::Errno::OVERFLOW)?; -    result.st_size = s64.st_size.try_into().map_err(|_| io::Errno::OVERFLOW)?; -    result.st_blksize = s64.st_blksize.try_into().map_err(|_| io::Errno::OVERFLOW)?; -    result.st_blocks = s64.st_blocks.try_into().map_err(|_| io::Errno::OVERFLOW)?; -    result.st_atime = s64.st_atime.try_into().map_err(|_| io::Errno::OVERFLOW)?; -    result.st_atime_nsec = s64 -        .st_atime_nsec -        .try_into() -        .map_err(|_| io::Errno::OVERFLOW)?; -    result.st_mtime = s64.st_mtime.try_into().map_err(|_| io::Errno::OVERFLOW)?; -    result.st_mtime_nsec = s64 -        .st_mtime_nsec -        .try_into() -        .map_err(|_| io::Errno::OVERFLOW)?; -    result.st_ctime = s64.st_ctime.try_into().map_err(|_| io::Errno::OVERFLOW)?; -    result.st_ctime_nsec = s64 -        .st_ctime_nsec -        .try_into() -        .map_err(|_| io::Errno::OVERFLOW)?; -    result.st_ino = s64.st_ino.try_into().map_err(|_| io::Errno::OVERFLOW)?; - -    Ok(result) -} - -#[cfg(linux_kernel)] -#[allow(non_upper_case_globals)] -mod sys { -    use super::{c, BorrowedFd, Statx}; - -    weak_or_syscall! { -        pub(super) fn statx( -            dirfd_: BorrowedFd<'_>, -            path: *const c::c_char, -            flags: c::c_int, -            mask: c::c_uint, -            buf: *mut Statx -        ) via SYS_statx -> c::c_int -    } -} - -#[cfg(linux_kernel)] -#[allow(non_upper_case_globals)] -pub(crate) fn statx( -    dirfd: BorrowedFd<'_>, -    path: &CStr, -    flags: AtFlags, -    mask: StatxFlags, -) -> io::Result<Statx> { -    // If a future Linux kernel adds more fields to `struct statx` and users -    // passing flags unknown to rustix in `StatxFlags`, we could end up -    // writing outside of the buffer. To prevent this possibility, we mask off -    // any flags that we don't know about. -    // -    // This includes `STATX__RESERVED`, which has a value that we know, but -    // which could take on arbitrary new meaning in the future. Linux currently -    // rejects this flag with `EINVAL`, so we do the same. -    // -    // This doesn't rely on `STATX_ALL` because [it's deprecated] and already -    // doesn't represent all the known flags. -    // -    // [it's deprecated]: https://patchwork.kernel.org/project/linux-fsdevel/patch/20200505095915.11275-7-mszeredi@redhat.com/ -    #[cfg(not(any(target_os = "android", target_env = "musl")))] -    const STATX__RESERVED: u32 = c::STATX__RESERVED as u32; -    #[cfg(any(target_os = "android", target_env = "musl"))] -    const STATX__RESERVED: u32 = linux_raw_sys::general::STATX__RESERVED; -    if (mask.bits() & STATX__RESERVED) == STATX__RESERVED { -        return Err(io::Errno::INVAL); -    } -    let mask = mask & StatxFlags::all(); - -    let mut statx_buf = MaybeUninit::<Statx>::uninit(); -    unsafe { -        ret(sys::statx( -            dirfd, -            c_str(path), -            bitflags_bits!(flags), -            mask.bits(), -            statx_buf.as_mut_ptr(), -        ))?; -        Ok(statx_buf.assume_init()) -    } -} - -#[cfg(linux_kernel)] -#[inline] -pub(crate) fn is_statx_available() -> bool { -    unsafe { -        // Call `statx` with null pointers so that if it fails for any reason -        // other than `EFAULT`, we know it's not supported. -        matches!( -            ret(sys::statx(CWD, null(), 0, 0, null_mut())), -            Err(io::Errno::FAULT) -        ) -    } -} - -#[cfg(apple)] -pub(crate) unsafe fn fcopyfile( -    from: BorrowedFd<'_>, -    to: BorrowedFd<'_>, -    state: copyfile_state_t, -    flags: CopyfileFlags, -) -> io::Result<()> { -    extern "C" { -        fn fcopyfile( -            from: c::c_int, -            to: c::c_int, -            state: copyfile_state_t, -            flags: c::c_uint, -        ) -> c::c_int; -    } - -    nonnegative_ret(fcopyfile( -        borrowed_fd(from), -        borrowed_fd(to), -        state, -        bitflags_bits!(flags), -    )) -} - -#[cfg(apple)] -pub(crate) fn copyfile_state_alloc() -> io::Result<copyfile_state_t> { -    extern "C" { -        fn copyfile_state_alloc() -> copyfile_state_t; -    } - -    let result = unsafe { copyfile_state_alloc() }; -    if result.0.is_null() { -        Err(io::Errno::last_os_error()) -    } else { -        Ok(result) -    } -} - -#[cfg(apple)] -pub(crate) unsafe fn copyfile_state_free(state: copyfile_state_t) -> io::Result<()> { -    extern "C" { -        fn copyfile_state_free(state: copyfile_state_t) -> c::c_int; -    } - -    nonnegative_ret(copyfile_state_free(state)) -} - -#[cfg(apple)] -const COPYFILE_STATE_COPIED: u32 = 8; - -#[cfg(apple)] -pub(crate) unsafe fn copyfile_state_get_copied(state: copyfile_state_t) -> io::Result<u64> { -    let mut copied = MaybeUninit::<u64>::uninit(); -    copyfile_state_get(state, COPYFILE_STATE_COPIED, copied.as_mut_ptr().cast())?; -    Ok(copied.assume_init()) -} - -#[cfg(apple)] -pub(crate) unsafe fn copyfile_state_get( -    state: copyfile_state_t, -    flag: u32, -    dst: *mut c::c_void, -) -> io::Result<()> { -    extern "C" { -        fn copyfile_state_get(state: copyfile_state_t, flag: u32, dst: *mut c::c_void) -> c::c_int; -    } - -    nonnegative_ret(copyfile_state_get(state, flag, dst)) -} - -#[cfg(all(apple, feature = "alloc"))] -pub(crate) fn getpath(fd: BorrowedFd<'_>) -> io::Result<CString> { -    // The use of `PATH_MAX` is generally not encouraged, but it -    // is inevitable in this case because macOS defines `fcntl` with -    // `F_GETPATH` in terms of `MAXPATHLEN`, and there are no -    // alternatives. If a better method is invented, it should be used -    // instead. -    let mut buf = vec![0; c::PATH_MAX as usize]; - -    // From the [macOS `fcntl` manual page]: -    // `F_GETPATH` - Get the path of the file descriptor `Fildes`. The argument -    //               must be a buffer of size `MAXPATHLEN` or greater. -    // -    // [macOS `fcntl` manual page]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html -    unsafe { -        ret(c::fcntl(borrowed_fd(fd), c::F_GETPATH, buf.as_mut_ptr()))?; -    } - -    let l = buf.iter().position(|&c| c == 0).unwrap(); -    buf.truncate(l); -    buf.shrink_to_fit(); - -    Ok(CString::new(buf).unwrap()) -} - -#[cfg(apple)] -pub(crate) fn fcntl_rdadvise(fd: BorrowedFd<'_>, offset: u64, len: u64) -> io::Result<()> { -    // From the [macOS `fcntl` manual page]: -    // `F_RDADVISE` - Issue an advisory read async with no copy to user. -    // -    // The `F_RDADVISE` command operates on the following structure which holds -    // information passed from the user to the system: -    // -    // ```c -    // struct radvisory { -    //      off_t   ra_offset;  /* offset into the file */ -    //      int     ra_count;   /* size of the read     */ -    // }; -    // ``` -    // -    // [macOS `fcntl` manual page]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html -    let ra_offset = match offset.try_into() { -        Ok(len) => len, -        // If this conversion fails, the user is providing an offset outside -        // any possible file extent, so just ignore it. -        Err(_) => return Ok(()), -    }; -    let ra_count = match len.try_into() { -        Ok(len) => len, -        // If this conversion fails, the user is providing a dubiously large -        // hint which is unlikely to improve performance. -        Err(_) => return Ok(()), -    }; -    unsafe { -        let radvisory = c::radvisory { -            ra_offset, -            ra_count, -        }; -        ret(c::fcntl(borrowed_fd(fd), c::F_RDADVISE, &radvisory)) -    } -} - -#[cfg(apple)] -pub(crate) fn fcntl_fullfsync(fd: BorrowedFd<'_>) -> io::Result<()> { -    unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_FULLFSYNC)) } -} - -#[cfg(apple)] -pub(crate) fn fcntl_nocache(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { -    unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_NOCACHE, value as c::c_int)) } -} - -#[cfg(apple)] -pub(crate) fn fcntl_global_nocache(fd: BorrowedFd<'_>, value: bool) -> io::Result<()> { -    unsafe { -        ret(c::fcntl( -            borrowed_fd(fd), -            c::F_GLOBAL_NOCACHE, -            value as c::c_int, -        )) -    } -} - -/// Convert `times` from a `futimens`/`utimensat` argument into `setattrlist` -/// arguments. -#[cfg(apple)] -fn times_to_attrlist(times: &Timestamps) -> (c::size_t, [c::timespec; 2], Attrlist) { -    // ABI details. -    const ATTR_CMN_MODTIME: u32 = 0x0000_0400; -    const ATTR_CMN_ACCTIME: u32 = 0x0000_1000; -    const ATTR_BIT_MAP_COUNT: u16 = 5; - -    let mut times = times.clone(); - -    // If we have any `UTIME_NOW` elements, replace them with the current time. -    if times.last_access.tv_nsec == c::UTIME_NOW || times.last_modification.tv_nsec == c::UTIME_NOW -    { -        let now = { -            let mut tv = c::timeval { -                tv_sec: 0, -                tv_usec: 0, -            }; -            unsafe { -                let r = c::gettimeofday(&mut tv, null_mut()); -                assert_eq!(r, 0); -            } -            c::timespec { -                tv_sec: tv.tv_sec, -                tv_nsec: (tv.tv_usec * 1000) as _, -            } -        }; -        if times.last_access.tv_nsec == c::UTIME_NOW { -            times.last_access = now; -        } -        if times.last_modification.tv_nsec == c::UTIME_NOW { -            times.last_modification = now; -        } -    } - -    // Pack the return values following the rules for [`getattrlist`]. -    // -    // [`getattrlist`]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getattrlist.2.html -    let mut times_size = 0; -    let mut attrs = Attrlist { -        bitmapcount: ATTR_BIT_MAP_COUNT, -        reserved: 0, -        commonattr: 0, -        volattr: 0, -        dirattr: 0, -        fileattr: 0, -        forkattr: 0, -    }; -    let mut return_times = [c::timespec { -        tv_sec: 0, -        tv_nsec: 0, -    }; 2]; -    let mut times_index = 0; -    if times.last_modification.tv_nsec != c::UTIME_OMIT { -        attrs.commonattr |= ATTR_CMN_MODTIME; -        return_times[times_index] = times.last_modification; -        times_index += 1; -        times_size += size_of::<c::timespec>(); -    } -    if times.last_access.tv_nsec != c::UTIME_OMIT { -        attrs.commonattr |= ATTR_CMN_ACCTIME; -        return_times[times_index] = times.last_access; -        times_size += size_of::<c::timespec>(); -    } - -    (times_size, return_times, attrs) -} - -/// Support type for `Attrlist`. -#[cfg(apple)] -type Attrgroup = u32; - -/// Attribute list for use with `setattrlist`. -#[cfg(apple)] -#[repr(C)] -struct Attrlist { -    bitmapcount: u16, -    reserved: u16, -    commonattr: Attrgroup, -    volattr: Attrgroup, -    dirattr: Attrgroup, -    fileattr: Attrgroup, -    forkattr: Attrgroup, -} - -#[cfg(any(apple, linux_kernel))] -pub(crate) fn getxattr(path: &CStr, name: &CStr, value: &mut [u8]) -> io::Result<usize> { -    let value_ptr = value.as_mut_ptr(); - -    #[cfg(not(apple))] -    unsafe { -        ret_usize(c::getxattr( -            path.as_ptr(), -            name.as_ptr(), -            value_ptr.cast::<c::c_void>(), -            value.len(), -        )) -    } - -    #[cfg(apple)] -    unsafe { -        ret_usize(c::getxattr( -            path.as_ptr(), -            name.as_ptr(), -            value_ptr.cast::<c::c_void>(), -            value.len(), -            0, -            0, -        )) -    } -} - -#[cfg(any(apple, linux_kernel))] -pub(crate) fn lgetxattr(path: &CStr, name: &CStr, value: &mut [u8]) -> io::Result<usize> { -    let value_ptr = value.as_mut_ptr(); - -    #[cfg(not(apple))] -    unsafe { -        ret_usize(c::lgetxattr( -            path.as_ptr(), -            name.as_ptr(), -            value_ptr.cast::<c::c_void>(), -            value.len(), -        )) -    } - -    #[cfg(apple)] -    unsafe { -        ret_usize(c::getxattr( -            path.as_ptr(), -            name.as_ptr(), -            value_ptr.cast::<c::c_void>(), -            value.len(), -            0, -            c::XATTR_NOFOLLOW, -        )) -    } -} - -#[cfg(any(apple, linux_kernel))] -pub(crate) fn fgetxattr(fd: BorrowedFd<'_>, name: &CStr, value: &mut [u8]) -> io::Result<usize> { -    let value_ptr = value.as_mut_ptr(); - -    #[cfg(not(apple))] -    unsafe { -        ret_usize(c::fgetxattr( -            borrowed_fd(fd), -            name.as_ptr(), -            value_ptr.cast::<c::c_void>(), -            value.len(), -        )) -    } - -    #[cfg(apple)] -    unsafe { -        ret_usize(c::fgetxattr( -            borrowed_fd(fd), -            name.as_ptr(), -            value_ptr.cast::<c::c_void>(), -            value.len(), -            0, -            0, -        )) -    } -} - -#[cfg(any(apple, linux_kernel))] -pub(crate) fn setxattr( -    path: &CStr, -    name: &CStr, -    value: &[u8], -    flags: XattrFlags, -) -> io::Result<()> { -    #[cfg(not(apple))] -    unsafe { -        ret(c::setxattr( -            path.as_ptr(), -            name.as_ptr(), -            value.as_ptr().cast::<c::c_void>(), -            value.len(), -            flags.bits() as i32, -        )) -    } - -    #[cfg(apple)] -    unsafe { -        ret(c::setxattr( -            path.as_ptr(), -            name.as_ptr(), -            value.as_ptr().cast::<c::c_void>(), -            value.len(), -            0, -            flags.bits() as i32, -        )) -    } -} - -#[cfg(any(apple, linux_kernel))] -pub(crate) fn lsetxattr( -    path: &CStr, -    name: &CStr, -    value: &[u8], -    flags: XattrFlags, -) -> io::Result<()> { -    #[cfg(not(apple))] -    unsafe { -        ret(c::lsetxattr( -            path.as_ptr(), -            name.as_ptr(), -            value.as_ptr().cast::<c::c_void>(), -            value.len(), -            flags.bits() as i32, -        )) -    } - -    #[cfg(apple)] -    unsafe { -        ret(c::setxattr( -            path.as_ptr(), -            name.as_ptr(), -            value.as_ptr().cast::<c::c_void>(), -            value.len(), -            0, -            flags.bits() as i32 | c::XATTR_NOFOLLOW, -        )) -    } -} - -#[cfg(any(apple, linux_kernel))] -pub(crate) fn fsetxattr( -    fd: BorrowedFd<'_>, -    name: &CStr, -    value: &[u8], -    flags: XattrFlags, -) -> io::Result<()> { -    #[cfg(not(apple))] -    unsafe { -        ret(c::fsetxattr( -            borrowed_fd(fd), -            name.as_ptr(), -            value.as_ptr().cast::<c::c_void>(), -            value.len(), -            flags.bits() as i32, -        )) -    } - -    #[cfg(apple)] -    unsafe { -        ret(c::fsetxattr( -            borrowed_fd(fd), -            name.as_ptr(), -            value.as_ptr().cast::<c::c_void>(), -            value.len(), -            0, -            flags.bits() as i32, -        )) -    } -} - -#[cfg(any(apple, linux_kernel))] -pub(crate) fn listxattr(path: &CStr, list: &mut [c::c_char]) -> io::Result<usize> { -    #[cfg(not(apple))] -    unsafe { -        ret_usize(c::listxattr(path.as_ptr(), list.as_mut_ptr(), list.len())) -    } - -    #[cfg(apple)] -    unsafe { -        ret_usize(c::listxattr( -            path.as_ptr(), -            list.as_mut_ptr(), -            list.len(), -            0, -        )) -    } -} - -#[cfg(any(apple, linux_kernel))] -pub(crate) fn llistxattr(path: &CStr, list: &mut [c::c_char]) -> io::Result<usize> { -    #[cfg(not(apple))] -    unsafe { -        ret_usize(c::llistxattr(path.as_ptr(), list.as_mut_ptr(), list.len())) -    } - -    #[cfg(apple)] -    unsafe { -        ret_usize(c::listxattr( -            path.as_ptr(), -            list.as_mut_ptr(), -            list.len(), -            c::XATTR_NOFOLLOW, -        )) -    } -} - -#[cfg(any(apple, linux_kernel))] -pub(crate) fn flistxattr(fd: BorrowedFd<'_>, list: &mut [c::c_char]) -> io::Result<usize> { -    let fd = borrowed_fd(fd); - -    #[cfg(not(apple))] -    unsafe { -        ret_usize(c::flistxattr(fd, list.as_mut_ptr(), list.len())) -    } - -    #[cfg(apple)] -    unsafe { -        ret_usize(c::flistxattr(fd, list.as_mut_ptr(), list.len(), 0)) -    } -} - -#[cfg(any(apple, linux_kernel))] -pub(crate) fn removexattr(path: &CStr, name: &CStr) -> io::Result<()> { -    #[cfg(not(apple))] -    unsafe { -        ret(c::removexattr(path.as_ptr(), name.as_ptr())) -    } - -    #[cfg(apple)] -    unsafe { -        ret(c::removexattr(path.as_ptr(), name.as_ptr(), 0)) -    } -} - -#[cfg(any(apple, linux_kernel))] -pub(crate) fn lremovexattr(path: &CStr, name: &CStr) -> io::Result<()> { -    #[cfg(not(apple))] -    unsafe { -        ret(c::lremovexattr(path.as_ptr(), name.as_ptr())) -    } - -    #[cfg(apple)] -    unsafe { -        ret(c::removexattr( -            path.as_ptr(), -            name.as_ptr(), -            c::XATTR_NOFOLLOW, -        )) -    } -} - -#[cfg(any(apple, linux_kernel))] -pub(crate) fn fremovexattr(fd: BorrowedFd<'_>, name: &CStr) -> io::Result<()> { -    let fd = borrowed_fd(fd); - -    #[cfg(not(apple))] -    unsafe { -        ret(c::fremovexattr(fd, name.as_ptr())) -    } - -    #[cfg(apple)] -    unsafe { -        ret(c::fremovexattr(fd, name.as_ptr(), 0)) -    } -} - -#[test] -fn test_sizes() { -    #[cfg(linux_kernel)] -    assert_eq_size!(c::loff_t, u64); - -    // Assert that `Timestamps` has the expected layout. If we're not fixing -    // y2038, libc's type should match ours. If we are, it's smaller. -    #[cfg(not(fix_y2038))] -    assert_eq_size!([c::timespec; 2], Timestamps); -    #[cfg(fix_y2038)] -    assert!(core::mem::size_of::<[c::timespec; 2]>() < core::mem::size_of::<Timestamps>()); -} diff --git a/vendor/rustix/src/backend/libc/fs/types.rs b/vendor/rustix/src/backend/libc/fs/types.rs deleted file mode 100644 index 19508c2..0000000 --- a/vendor/rustix/src/backend/libc/fs/types.rs +++ /dev/null @@ -1,1164 +0,0 @@ -use crate::backend::c; -use bitflags::bitflags; - -#[cfg(not(any(target_os = "espidf", target_os = "vita")))] -bitflags! { -    /// `*_OK` constants for use with [`accessat`]. -    /// -    /// [`accessat`]: fn.accessat.html -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct Access: c::c_int { -        /// `R_OK` -        const READ_OK = c::R_OK; - -        /// `W_OK` -        const WRITE_OK = c::W_OK; - -        /// `X_OK` -        const EXEC_OK = c::X_OK; - -        /// `F_OK` -        const EXISTS = c::F_OK; - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -#[cfg(not(any(target_os = "espidf", target_os = "redox")))] -bitflags! { -    /// `AT_*` constants for use with [`openat`], [`statat`], and other `*at` -    /// functions. -    /// -    /// [`openat`]: crate::fs::openat -    /// [`statat`]: crate::fs::statat -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct AtFlags: u32 { -        /// `AT_SYMLINK_NOFOLLOW` -        const SYMLINK_NOFOLLOW = bitcast!(c::AT_SYMLINK_NOFOLLOW); - -        /// `AT_EACCESS` -        #[cfg(not(any(target_os = "emscripten", target_os = "android")))] -        const EACCESS = bitcast!(c::AT_EACCESS); - -        /// `AT_REMOVEDIR` -        const REMOVEDIR = bitcast!(c::AT_REMOVEDIR); - -        /// `AT_SYMLINK_FOLLOW` -        const SYMLINK_FOLLOW = bitcast!(c::AT_SYMLINK_FOLLOW); - -        /// `AT_NO_AUTOMOUNT` -        #[cfg(any(linux_like, target_os = "fuchsia"))] -        const NO_AUTOMOUNT = bitcast!(c::AT_NO_AUTOMOUNT); - -        /// `AT_EMPTY_PATH` -        #[cfg(any( -            linux_kernel, -            target_os = "freebsd", -            target_os = "fuchsia", -        ))] -        const EMPTY_PATH = bitcast!(c::AT_EMPTY_PATH); - -        /// `AT_RESOLVE_BENEATH` -        #[cfg(target_os = "freebsd")] -        const RESOLVE_BENEATH = bitcast!(c::AT_RESOLVE_BENEATH); - -        /// `AT_STATX_SYNC_AS_STAT` -        #[cfg(all(target_os = "linux", target_env = "gnu"))] -        const STATX_SYNC_AS_STAT = bitcast!(c::AT_STATX_SYNC_AS_STAT); - -        /// `AT_STATX_FORCE_SYNC` -        #[cfg(all(target_os = "linux", target_env = "gnu"))] -        const STATX_FORCE_SYNC = bitcast!(c::AT_STATX_FORCE_SYNC); - -        /// `AT_STATX_DONT_SYNC` -        #[cfg(all(target_os = "linux", target_env = "gnu"))] -        const STATX_DONT_SYNC = bitcast!(c::AT_STATX_DONT_SYNC); - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -bitflags! { -    /// `S_I*` constants for use with [`openat`], [`chmodat`], and [`fchmod`]. -    /// -    /// [`openat`]: crate::fs::openat -    /// [`chmodat`]: crate::fs::chmodat -    /// [`fchmod`]: crate::fs::fchmod -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct Mode: RawMode { -        /// `S_IRWXU` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const RWXU = c::S_IRWXU as RawMode; - -        /// `S_IRUSR` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const RUSR = c::S_IRUSR as RawMode; - -        /// `S_IWUSR` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const WUSR = c::S_IWUSR as RawMode; - -        /// `S_IXUSR` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const XUSR = c::S_IXUSR as RawMode; - -        /// `S_IRWXG` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const RWXG = c::S_IRWXG as RawMode; - -        /// `S_IRGRP` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const RGRP = c::S_IRGRP as RawMode; - -        /// `S_IWGRP` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const WGRP = c::S_IWGRP as RawMode; - -        /// `S_IXGRP` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const XGRP = c::S_IXGRP as RawMode; - -        /// `S_IRWXO` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const RWXO = c::S_IRWXO as RawMode; - -        /// `S_IROTH` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const ROTH = c::S_IROTH as RawMode; - -        /// `S_IWOTH` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const WOTH = c::S_IWOTH as RawMode; - -        /// `S_IXOTH` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const XOTH = c::S_IXOTH as RawMode; - -        /// `S_ISUID` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const SUID = c::S_ISUID as RawMode; - -        /// `S_ISGID` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const SGID = c::S_ISGID as RawMode; - -        /// `S_ISVTX` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const SVTX = c::S_ISVTX as RawMode; - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -#[cfg(not(target_os = "espidf"))] -impl Mode { -    /// Construct a `Mode` from the mode bits of the `st_mode` field of a -    /// `Mode`. -    #[inline] -    pub const fn from_raw_mode(st_mode: RawMode) -> Self { -        Self::from_bits_truncate(st_mode) -    } - -    /// Construct an `st_mode` value from a `Mode`. -    #[inline] -    pub const fn as_raw_mode(self) -> RawMode { -        self.bits() -    } -} - -#[cfg(not(target_os = "espidf"))] -impl From<RawMode> for Mode { -    /// Support conversions from raw mode values to `Mode`. -    /// -    /// ``` -    /// use rustix::fs::{Mode, RawMode}; -    /// assert_eq!(Mode::from(0o700), Mode::RWXU); -    /// ``` -    #[inline] -    fn from(st_mode: RawMode) -> Self { -        Self::from_raw_mode(st_mode) -    } -} - -#[cfg(not(target_os = "espidf"))] -impl From<Mode> for RawMode { -    /// Support conversions from `Mode` to raw mode values. -    /// -    /// ``` -    /// use rustix::fs::{Mode, RawMode}; -    /// assert_eq!(RawMode::from(Mode::RWXU), 0o700); -    /// ``` -    #[inline] -    fn from(mode: Mode) -> Self { -        mode.as_raw_mode() -    } -} - -bitflags! { -    /// `O_*` constants for use with [`openat`]. -    /// -    /// [`openat`]: crate::fs::openat -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct OFlags: u32 { -        /// `O_ACCMODE` -        const ACCMODE = bitcast!(c::O_ACCMODE); - -        /// Similar to `ACCMODE`, but just includes the read/write flags, and -        /// no other flags. -        /// -        /// On some platforms, `PATH` may be included in `ACCMODE`, when -        /// sometimes we really just want the read/write bits. Caution is -        /// indicated, as the presence of `PATH` may mean that the read/write -        /// bits don't have their usual meaning. -        const RWMODE = bitcast!(c::O_RDONLY | c::O_WRONLY | c::O_RDWR); - -        /// `O_APPEND` -        const APPEND = bitcast!(c::O_APPEND); - -        /// `O_CREAT` -        #[doc(alias = "CREAT")] -        const CREATE = bitcast!(c::O_CREAT); - -        /// `O_DIRECTORY` -        #[cfg(not(target_os = "espidf"))] -        const DIRECTORY = bitcast!(c::O_DIRECTORY); - -        /// `O_DSYNC` -        #[cfg(not(any(target_os = "dragonfly", target_os = "espidf", target_os = "l4re", target_os = "redox", target_os = "vita")))] -        const DSYNC = bitcast!(c::O_DSYNC); - -        /// `O_EXCL` -        const EXCL = bitcast!(c::O_EXCL); - -        /// `O_FSYNC` -        #[cfg(any( -            bsd, -            all(target_os = "linux", not(target_env = "musl")), -        ))] -        const FSYNC = bitcast!(c::O_FSYNC); - -        /// `O_NOFOLLOW` -        #[cfg(not(target_os = "espidf"))] -        const NOFOLLOW = bitcast!(c::O_NOFOLLOW); - -        /// `O_NONBLOCK` -        const NONBLOCK = bitcast!(c::O_NONBLOCK); - -        /// `O_RDONLY` -        const RDONLY = bitcast!(c::O_RDONLY); - -        /// `O_WRONLY` -        const WRONLY = bitcast!(c::O_WRONLY); - -        /// `O_RDWR` -        /// -        /// This is not equal to `RDONLY | WRONLY`. It's a distinct flag. -        const RDWR = bitcast!(c::O_RDWR); - -        /// `O_NOCTTY` -        #[cfg(not(any(target_os = "espidf", target_os = "l4re", target_os = "redox", target_os = "vita")))] -        const NOCTTY = bitcast!(c::O_NOCTTY); - -        /// `O_RSYNC` -        #[cfg(any( -            linux_kernel, -            netbsdlike, -            target_os = "emscripten", -            target_os = "wasi", -        ))] -        const RSYNC = bitcast!(c::O_RSYNC); - -        /// `O_SYNC` -        #[cfg(not(any(target_os = "l4re", target_os = "redox")))] -        const SYNC = bitcast!(c::O_SYNC); - -        /// `O_TRUNC` -        const TRUNC = bitcast!(c::O_TRUNC); - -        /// `O_PATH` -        #[cfg(any( -            linux_kernel, -            target_os = "emscripten", -            target_os = "freebsd", -            target_os = "fuchsia", -            target_os = "redox", -        ))] -        const PATH = bitcast!(c::O_PATH); - -        /// `O_CLOEXEC` -        const CLOEXEC = bitcast!(c::O_CLOEXEC); - -        /// `O_TMPFILE` -        #[cfg(any( -            linux_kernel, -            target_os = "emscripten", -            target_os = "fuchsia", -        ))] -        const TMPFILE = bitcast!(c::O_TMPFILE); - -        /// `O_NOATIME` -        #[cfg(any( -            linux_kernel, -            target_os = "fuchsia", -        ))] -        const NOATIME = bitcast!(c::O_NOATIME); - -        /// `O_DIRECT` -        #[cfg(any( -            linux_kernel, -            target_os = "emscripten", -            target_os = "freebsd", -            target_os = "fuchsia", -            target_os = "netbsd", -        ))] -        const DIRECT = bitcast!(c::O_DIRECT); - -        /// `O_RESOLVE_BENEATH` -        #[cfg(target_os = "freebsd")] -        const RESOLVE_BENEATH = bitcast!(c::O_RESOLVE_BENEATH); - -        /// `O_EMPTY_PATH` -        #[cfg(target_os = "freebsd")] -        const EMPTY_PATH = bitcast!(c::O_EMPTY_PATH); - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -#[cfg(apple)] -bitflags! { -    /// `CLONE_*` constants for use with [`fclonefileat`]. -    /// -    /// [`fclonefileat`]: crate::fs::fclonefileat -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct CloneFlags: u32 { -        /// `CLONE_NOFOLLOW` -        const NOFOLLOW = 1; - -        /// `CLONE_NOOWNERCOPY` -        const NOOWNERCOPY = 2; - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -#[cfg(apple)] -mod copyfile { -    pub(super) const ACL: u32 = 1 << 0; -    pub(super) const STAT: u32 = 1 << 1; -    pub(super) const XATTR: u32 = 1 << 2; -    pub(super) const DATA: u32 = 1 << 3; -    pub(super) const SECURITY: u32 = STAT | ACL; -    pub(super) const METADATA: u32 = SECURITY | XATTR; -    pub(super) const ALL: u32 = METADATA | DATA; -} - -#[cfg(apple)] -bitflags! { -    /// `COPYFILE_*` constants for use with [`fcopyfile`]. -    /// -    /// [`fcopyfile`]: crate::fs::fcopyfile -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct CopyfileFlags: c::c_uint { -        /// `COPYFILE_ACL` -        const ACL = copyfile::ACL; - -        /// `COPYFILE_STAT` -        const STAT = copyfile::STAT; - -        /// `COPYFILE_XATTR` -        const XATTR = copyfile::XATTR; - -        /// `COPYFILE_DATA` -        const DATA = copyfile::DATA; - -        /// `COPYFILE_SECURITY` -        const SECURITY = copyfile::SECURITY; - -        /// `COPYFILE_METADATA` -        const METADATA = copyfile::METADATA; - -        /// `COPYFILE_ALL` -        const ALL = copyfile::ALL; - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -#[cfg(linux_kernel)] -bitflags! { -    /// `RESOLVE_*` constants for use with [`openat2`]. -    /// -    /// [`openat2`]: crate::fs::openat2 -    #[repr(transparent)] -    #[derive(Default, Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct ResolveFlags: u64 { -        /// `RESOLVE_NO_XDEV` -        const NO_XDEV = 0x01; - -        /// `RESOLVE_NO_MAGICLINKS` -        const NO_MAGICLINKS = 0x02; - -        /// `RESOLVE_NO_SYMLINKS` -        const NO_SYMLINKS = 0x04; - -        /// `RESOLVE_BENEATH` -        const BENEATH = 0x08; - -        /// `RESOLVE_IN_ROOT` -        const IN_ROOT = 0x10; - -        /// `RESOLVE_CACHED` (since Linux 5.12) -        const CACHED = 0x20; - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -#[cfg(linux_kernel)] -bitflags! { -    /// `RENAME_*` constants for use with [`renameat_with`]. -    /// -    /// [`renameat_with`]: crate::fs::renameat_with -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct RenameFlags: c::c_uint { -        /// `RENAME_EXCHANGE` -        const EXCHANGE = bitcast!(c::RENAME_EXCHANGE); - -        /// `RENAME_NOREPLACE` -        const NOREPLACE = bitcast!(c::RENAME_NOREPLACE); - -        /// `RENAME_WHITEOUT` -        const WHITEOUT = bitcast!(c::RENAME_WHITEOUT); - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -/// `S_IF*` constants for use with [`mknodat`] and [`Stat`]'s `st_mode` field. -/// -/// [`mknodat`]: crate::fs::mknodat -/// [`Stat`]: crate::fs::Stat -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum FileType { -    /// `S_IFREG` -    RegularFile = c::S_IFREG as isize, - -    /// `S_IFDIR` -    Directory = c::S_IFDIR as isize, - -    /// `S_IFLNK` -    Symlink = c::S_IFLNK as isize, - -    /// `S_IFIFO` -    #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. -    #[doc(alias = "IFO")] -    Fifo = c::S_IFIFO as isize, - -    /// `S_IFSOCK` -    #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. -    Socket = c::S_IFSOCK as isize, - -    /// `S_IFCHR` -    CharacterDevice = c::S_IFCHR as isize, - -    /// `S_IFBLK` -    BlockDevice = c::S_IFBLK as isize, - -    /// An unknown filesystem object. -    Unknown, -} - -impl FileType { -    /// Construct a `FileType` from the `S_IFMT` bits of the `st_mode` field of -    /// a `Stat`. -    #[inline] -    pub const fn from_raw_mode(st_mode: RawMode) -> Self { -        match (st_mode as c::mode_t) & c::S_IFMT { -            c::S_IFREG => Self::RegularFile, -            c::S_IFDIR => Self::Directory, -            c::S_IFLNK => Self::Symlink, -            #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. -            c::S_IFIFO => Self::Fifo, -            #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. -            c::S_IFSOCK => Self::Socket, -            c::S_IFCHR => Self::CharacterDevice, -            c::S_IFBLK => Self::BlockDevice, -            _ => Self::Unknown, -        } -    } - -    /// Construct an `st_mode` value from a `FileType`. -    #[inline] -    pub const fn as_raw_mode(self) -> RawMode { -        match self { -            Self::RegularFile => c::S_IFREG as RawMode, -            Self::Directory => c::S_IFDIR as RawMode, -            Self::Symlink => c::S_IFLNK as RawMode, -            #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFIFO`. -            Self::Fifo => c::S_IFIFO as RawMode, -            #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `S_IFSOCK`. -            Self::Socket => c::S_IFSOCK as RawMode, -            Self::CharacterDevice => c::S_IFCHR as RawMode, -            Self::BlockDevice => c::S_IFBLK as RawMode, -            Self::Unknown => c::S_IFMT as RawMode, -        } -    } - -    /// Construct a `FileType` from the `d_type` field of a `c::dirent`. -    #[cfg(not(any( -        solarish, -        target_os = "aix", -        target_os = "espidf", -        target_os = "haiku", -        target_os = "nto", -        target_os = "redox", -        target_os = "vita" -    )))] -    #[inline] -    pub(crate) const fn from_dirent_d_type(d_type: u8) -> Self { -        match d_type { -            c::DT_REG => Self::RegularFile, -            c::DT_DIR => Self::Directory, -            c::DT_LNK => Self::Symlink, -            #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `DT_SOCK`. -            c::DT_SOCK => Self::Socket, -            #[cfg(not(target_os = "wasi"))] // TODO: Use WASI's `DT_FIFO`. -            c::DT_FIFO => Self::Fifo, -            c::DT_CHR => Self::CharacterDevice, -            c::DT_BLK => Self::BlockDevice, -            // c::DT_UNKNOWN | -            _ => Self::Unknown, -        } -    } -} - -/// `POSIX_FADV_*` constants for use with [`fadvise`]. -/// -/// [`fadvise`]: crate::fs::fadvise -#[cfg(not(any( -    apple, -    netbsdlike, -    solarish, -    target_os = "dragonfly", -    target_os = "espidf", -    target_os = "haiku", -    target_os = "redox", -    target_os = "vita", -)))] -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -#[repr(u32)] -pub enum Advice { -    /// `POSIX_FADV_NORMAL` -    Normal = c::POSIX_FADV_NORMAL as c::c_uint, - -    /// `POSIX_FADV_SEQUENTIAL` -    Sequential = c::POSIX_FADV_SEQUENTIAL as c::c_uint, - -    /// `POSIX_FADV_RANDOM` -    Random = c::POSIX_FADV_RANDOM as c::c_uint, - -    /// `POSIX_FADV_NOREUSE` -    NoReuse = c::POSIX_FADV_NOREUSE as c::c_uint, - -    /// `POSIX_FADV_WILLNEED` -    WillNeed = c::POSIX_FADV_WILLNEED as c::c_uint, - -    /// `POSIX_FADV_DONTNEED` -    DontNeed = c::POSIX_FADV_DONTNEED as c::c_uint, -} - -#[cfg(any(linux_kernel, target_os = "freebsd"))] -bitflags! { -    /// `MFD_*` constants for use with [`memfd_create`]. -    /// -    /// [`memfd_create`]: crate::fs::memfd_create -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct MemfdFlags: c::c_uint { -        /// `MFD_CLOEXEC` -        const CLOEXEC = c::MFD_CLOEXEC; - -        /// `MFD_ALLOW_SEALING` -        const ALLOW_SEALING = c::MFD_ALLOW_SEALING; - -        /// `MFD_HUGETLB` (since Linux 4.14) -        const HUGETLB = c::MFD_HUGETLB; - -        /// `MFD_HUGE_64KB` -        const HUGE_64KB = c::MFD_HUGE_64KB; -        /// `MFD_HUGE_512JB` -        const HUGE_512KB = c::MFD_HUGE_512KB; -        /// `MFD_HUGE_1MB` -        const HUGE_1MB = c::MFD_HUGE_1MB; -        /// `MFD_HUGE_2MB` -        const HUGE_2MB = c::MFD_HUGE_2MB; -        /// `MFD_HUGE_8MB` -        const HUGE_8MB = c::MFD_HUGE_8MB; -        /// `MFD_HUGE_16MB` -        const HUGE_16MB = c::MFD_HUGE_16MB; -        /// `MFD_HUGE_32MB` -        const HUGE_32MB = c::MFD_HUGE_32MB; -        /// `MFD_HUGE_256MB` -        const HUGE_256MB = c::MFD_HUGE_256MB; -        /// `MFD_HUGE_512MB` -        const HUGE_512MB = c::MFD_HUGE_512MB; -        /// `MFD_HUGE_1GB` -        const HUGE_1GB = c::MFD_HUGE_1GB; -        /// `MFD_HUGE_2GB` -        const HUGE_2GB = c::MFD_HUGE_2GB; -        /// `MFD_HUGE_16GB` -        const HUGE_16GB = c::MFD_HUGE_16GB; - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -#[cfg(any(linux_kernel, target_os = "freebsd", target_os = "fuchsia"))] -bitflags! { -    /// `F_SEAL_*` constants for use with [`fcntl_add_seals`] and -    /// [`fcntl_get_seals`]. -    /// -    /// [`fcntl_add_seals`]: crate::fs::fcntl_add_seals -    /// [`fcntl_get_seals`]: crate::fs::fcntl_get_seals -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct SealFlags: u32 { -        /// `F_SEAL_SEAL` -        const SEAL = bitcast!(c::F_SEAL_SEAL); -        /// `F_SEAL_SHRINK` -        const SHRINK = bitcast!(c::F_SEAL_SHRINK); -        /// `F_SEAL_GROW` -        const GROW = bitcast!(c::F_SEAL_GROW); -        /// `F_SEAL_WRITE` -        const WRITE = bitcast!(c::F_SEAL_WRITE); -        /// `F_SEAL_FUTURE_WRITE` (since Linux 5.1) -        #[cfg(linux_kernel)] -        const FUTURE_WRITE = bitcast!(c::F_SEAL_FUTURE_WRITE); - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -#[cfg(all(target_os = "linux", target_env = "gnu"))] -bitflags! { -    /// `STATX_*` constants for use with [`statx`]. -    /// -    /// [`statx`]: crate::fs::statx -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct StatxFlags: u32 { -        /// `STATX_TYPE` -        const TYPE = c::STATX_TYPE; - -        /// `STATX_MODE` -        const MODE = c::STATX_MODE; - -        /// `STATX_NLINK` -        const NLINK = c::STATX_NLINK; - -        /// `STATX_UID` -        const UID = c::STATX_UID; - -        /// `STATX_GID` -        const GID = c::STATX_GID; - -        /// `STATX_ATIME` -        const ATIME = c::STATX_ATIME; - -        /// `STATX_MTIME` -        const MTIME = c::STATX_MTIME; - -        /// `STATX_CTIME` -        const CTIME = c::STATX_CTIME; - -        /// `STATX_INO` -        const INO = c::STATX_INO; - -        /// `STATX_SIZE` -        const SIZE = c::STATX_SIZE; - -        /// `STATX_BLOCKS` -        const BLOCKS = c::STATX_BLOCKS; - -        /// `STATX_BASIC_STATS` -        const BASIC_STATS = c::STATX_BASIC_STATS; - -        /// `STATX_BTIME` -        const BTIME = c::STATX_BTIME; - -        /// `STATX_MNT_ID` (since Linux 5.8) -        const MNT_ID = c::STATX_MNT_ID; - -        /// `STATX_DIOALIGN` (since Linux 6.1) -        const DIOALIGN = c::STATX_DIOALIGN; - -        /// `STATX_ALL` -        const ALL = c::STATX_ALL; - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -#[cfg(any( -    target_os = "android", -    all(target_os = "linux", not(target_env = "gnu")), -))] -bitflags! { -    /// `STATX_*` constants for use with [`statx`]. -    /// -    /// [`statx`]: crate::fs::statx -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct StatxFlags: u32 { -        /// `STATX_TYPE` -        const TYPE = 0x0001; - -        /// `STATX_MODE` -        const MODE = 0x0002; - -        /// `STATX_NLINK` -        const NLINK = 0x0004; - -        /// `STATX_UID` -        const UID = 0x0008; - -        /// `STATX_GID` -        const GID = 0x0010; - -        /// `STATX_ATIME` -        const ATIME = 0x0020; - -        /// `STATX_MTIME` -        const MTIME = 0x0040; - -        /// `STATX_CTIME` -        const CTIME = 0x0080; - -        /// `STATX_INO` -        const INO = 0x0100; - -        /// `STATX_SIZE` -        const SIZE = 0x0200; - -        /// `STATX_BLOCKS` -        const BLOCKS = 0x0400; - -        /// `STATX_BASIC_STATS` -        const BASIC_STATS = 0x07ff; - -        /// `STATX_BTIME` -        const BTIME = 0x800; - -        /// `STATX_MNT_ID` (since Linux 5.8) -        const MNT_ID = 0x1000; - -        /// `STATX_ALL` -        const ALL = 0xfff; - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -#[cfg(not(any( -    netbsdlike, -    solarish, -    target_os = "aix", -    target_os = "espidf", -    target_os = "nto", -    target_os = "redox", -    target_os = "vita" -)))] -bitflags! { -    /// `FALLOC_FL_*` constants for use with [`fallocate`]. -    /// -    /// [`fallocate`]: crate::fs::fallocate -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct FallocateFlags: u32 { -        /// `FALLOC_FL_KEEP_SIZE` -        #[cfg(not(any( -            bsd, -            target_os = "aix", -            target_os = "haiku", -            target_os = "hurd", -            target_os = "wasi", -        )))] -        const KEEP_SIZE = bitcast!(c::FALLOC_FL_KEEP_SIZE); -        /// `FALLOC_FL_PUNCH_HOLE` -        #[cfg(not(any( -            bsd, -            target_os = "aix", -            target_os = "haiku", -            target_os = "hurd", -            target_os = "wasi", -        )))] -        const PUNCH_HOLE = bitcast!(c::FALLOC_FL_PUNCH_HOLE); -        /// `FALLOC_FL_NO_HIDE_STALE` -        #[cfg(not(any( -            bsd, -            target_os = "aix", -            target_os = "emscripten", -            target_os = "fuchsia", -            target_os = "haiku", -            target_os = "hurd", -            target_os = "l4re", -            target_os = "linux", -            target_os = "wasi", -        )))] -        const NO_HIDE_STALE = bitcast!(c::FALLOC_FL_NO_HIDE_STALE); -        /// `FALLOC_FL_COLLAPSE_RANGE` -        #[cfg(not(any( -            bsd, -            target_os = "aix", -            target_os = "haiku", -            target_os = "hurd", -            target_os = "emscripten", -            target_os = "wasi", -        )))] -        const COLLAPSE_RANGE = bitcast!(c::FALLOC_FL_COLLAPSE_RANGE); -        /// `FALLOC_FL_ZERO_RANGE` -        #[cfg(not(any( -            bsd, -            target_os = "aix", -            target_os = "haiku", -            target_os = "hurd", -            target_os = "emscripten", -            target_os = "wasi", -        )))] -        const ZERO_RANGE = bitcast!(c::FALLOC_FL_ZERO_RANGE); -        /// `FALLOC_FL_INSERT_RANGE` -        #[cfg(not(any( -            bsd, -            target_os = "aix", -            target_os = "haiku", -            target_os = "hurd", -            target_os = "emscripten", -            target_os = "wasi", -        )))] -        const INSERT_RANGE = bitcast!(c::FALLOC_FL_INSERT_RANGE); -        /// `FALLOC_FL_UNSHARE_RANGE` -        #[cfg(not(any( -            bsd, -            target_os = "aix", -            target_os = "haiku", -            target_os = "hurd", -            target_os = "emscripten", -            target_os = "wasi", -        )))] -        const UNSHARE_RANGE = bitcast!(c::FALLOC_FL_UNSHARE_RANGE); - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -bitflags! { -    /// `ST_*` constants for use with [`StatVfs`]. -    #[repr(transparent)] -    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] -    pub struct StatVfsMountFlags: u64 { -        /// `ST_MANDLOCK` -        #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] -        const MANDLOCK = c::ST_MANDLOCK as u64; - -        /// `ST_NOATIME` -        #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] -        const NOATIME = c::ST_NOATIME as u64; - -        /// `ST_NODEV` -        #[cfg(any( -            linux_kernel, -            target_os = "aix", -            target_os = "emscripten", -            target_os = "fuchsia" -        ))] -        const NODEV = c::ST_NODEV as u64; - -        /// `ST_NODIRATIME` -        #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] -        const NODIRATIME = c::ST_NODIRATIME as u64; - -        /// `ST_NOEXEC` -        #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] -        const NOEXEC = c::ST_NOEXEC as u64; - -        /// `ST_NOSUID` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const NOSUID = c::ST_NOSUID as u64; - -        /// `ST_RDONLY` -        #[cfg(not(any(target_os = "espidf", target_os = "vita")))] -        const RDONLY = c::ST_RDONLY as u64; - -        /// `ST_RELATIME` -        #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] -        const RELATIME = c::ST_RELATIME as u64; - -        /// `ST_SYNCHRONOUS` -        #[cfg(any(linux_kernel, target_os = "emscripten", target_os = "fuchsia"))] -        const SYNCHRONOUS = c::ST_SYNCHRONOUS as u64; - -        /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> -        const _ = !0; -    } -} - -/// `LOCK_*` constants for use with [`flock`] and [`fcntl_lock`]. -/// -/// [`flock`]: crate::fs::flock -/// [`fcntl_lock`]: crate::fs::fcntl_lock -#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(u32)] -pub enum FlockOperation { -    /// `LOCK_SH` -    LockShared = bitcast!(c::LOCK_SH), -    /// `LOCK_EX` -    LockExclusive = bitcast!(c::LOCK_EX), -    /// `LOCK_UN` -    Unlock = bitcast!(c::LOCK_UN), -    /// `LOCK_SH | LOCK_NB` -    NonBlockingLockShared = bitcast!(c::LOCK_SH | c::LOCK_NB), -    /// `LOCK_EX | LOCK_NB` -    NonBlockingLockExclusive = bitcast!(c::LOCK_EX | c::LOCK_NB), -    /// `LOCK_UN | LOCK_NB` -    NonBlockingUnlock = bitcast!(c::LOCK_UN | c::LOCK_NB), -} - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -#[cfg(not(any(linux_like, target_os = "hurd")))] -pub type Stat = c::stat; - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -#[cfg(any( -    all(linux_kernel, target_pointer_width = "64"), -    target_os = "hurd", -    target_os = "emscripten", -    target_os = "l4re", -))] -pub type Stat = c::stat64; - -/// `struct stat` for use with [`statat`] and [`fstat`]. -/// -/// [`statat`]: crate::fs::statat -/// [`fstat`]: crate::fs::fstat -// On 32-bit, Linux's `struct stat64` has a 32-bit `st_mtime` and friends, so -// we use our own struct, populated from `statx` where possible, to avoid the -// y2038 bug. -#[cfg(all(linux_kernel, target_pointer_width = "32"))] -#[repr(C)] -#[derive(Debug, Copy, Clone)] -#[allow(missing_docs)] -pub struct Stat { -    pub st_dev: u64, -    pub st_mode: u32, -    pub st_nlink: u32, -    pub st_uid: u32, -    pub st_gid: u32, -    pub st_rdev: u64, -    pub st_size: i64, -    pub st_blksize: u32, -    pub st_blocks: u64, -    pub st_atime: u64, -    pub st_atime_nsec: u32, -    pub st_mtime: u64, -    pub st_mtime_nsec: u32, -    pub st_ctime: u64, -    pub st_ctime_nsec: u32, -    pub st_ino: u64, -} - -/// `struct statfs` for use with [`statfs`] and [`fstatfs`]. -/// -/// [`statfs`]: crate::fs::statfs -/// [`fstatfs`]: crate::fs::fstatfs -#[cfg(not(any( -    linux_like, -    solarish, -    target_os = "espidf", -    target_os = "haiku", -    target_os = "netbsd", -    target_os = "nto", -    target_os = "redox", -    target_os = "vita", -    target_os = "wasi", -)))] -#[allow(clippy::module_name_repetitions)] -pub type StatFs = c::statfs; - -/// `struct statfs` for use with [`statfs`] and [`fstatfs`]. -/// -/// [`statfs`]: crate::fs::statfs -/// [`fstatfs`]: crate::fs::fstatfs -#[cfg(linux_like)] -pub type StatFs = c::statfs64; - -/// `struct statvfs` for use with [`statvfs`] and [`fstatvfs`]. -/// -/// [`statvfs`]: crate::fs::statvfs -/// [`fstatvfs`]: crate::fs::fstatvfs -#[cfg(not(any(target_os = "haiku", target_os = "redox", target_os = "wasi")))] -#[allow(missing_docs)] -pub struct StatVfs { -    pub f_bsize: u64, -    pub f_frsize: u64, -    pub f_blocks: u64, -    pub f_bfree: u64, -    pub f_bavail: u64, -    pub f_files: u64, -    pub f_ffree: u64, -    pub f_favail: u64, -    pub f_fsid: u64, -    pub f_flag: StatVfsMountFlags, -    pub f_namemax: u64, -} - -/// `struct statx` for use with [`statx`]. -/// -/// [`statx`]: crate::fs::statx -#[cfg(all(target_os = "linux", target_env = "gnu"))] -// Use the glibc `struct statx`. -pub type Statx = c::statx; - -/// `struct statx_timestamp` for use with [`Statx`]. -#[cfg(all(target_os = "linux", target_env = "gnu"))] -// Use the glibc `struct statx_timestamp`. -pub type StatxTimestamp = c::statx; - -/// `struct statx` for use with [`statx`]. -/// -/// [`statx`]: crate::fs::statx -// Non-glibc ABIs don't currently declare a `struct statx`, so we declare it -// ourselves. -#[cfg(any( -    target_os = "android", -    all(target_os = "linux", not(target_env = "gnu")), -))] -#[repr(C)] -#[allow(missing_docs)] -pub struct Statx { -    pub stx_mask: u32, -    pub stx_blksize: u32, -    pub stx_attributes: u64, -    pub stx_nlink: u32, -    pub stx_uid: u32, -    pub stx_gid: u32, -    pub stx_mode: u16, -    __statx_pad1: [u16; 1], -    pub stx_ino: u64, -    pub stx_size: u64, -    pub stx_blocks: u64, -    pub stx_attributes_mask: u64, -    pub stx_atime: StatxTimestamp, -    pub stx_btime: StatxTimestamp, -    pub stx_ctime: StatxTimestamp, -    pub stx_mtime: StatxTimestamp, -    pub stx_rdev_major: u32, -    pub stx_rdev_minor: u32, -    pub stx_dev_major: u32, -    pub stx_dev_minor: u32, -    pub stx_mnt_id: u64, -    __statx_pad2: u64, -    __statx_pad3: [u64; 12], -} - -/// `struct statx_timestamp` for use with [`Statx`]. -// Non-glibc ABIs don't currently declare a `struct statx_timestamp`, so we -// declare it ourselves. -#[cfg(any( -    target_os = "android", -    all(target_os = "linux", not(target_env = "gnu")), -))] -#[repr(C)] -#[allow(missing_docs)] -pub struct StatxTimestamp { -    pub tv_sec: i64, -    pub tv_nsec: u32, -    pub __statx_timestamp_pad1: [i32; 1], -} - -/// `mode_t` -#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] -pub type RawMode = c::mode_t; - -/// `mode_t` -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -pub type RawMode = c::c_uint; - -/// `dev_t` -#[cfg(not(all(target_os = "android", target_pointer_width = "32")))] -pub type Dev = c::dev_t; - -/// `dev_t` -#[cfg(all(target_os = "android", target_pointer_width = "32"))] -pub type Dev = c::c_ulonglong; - -/// `__fsword_t` -#[cfg(all( -    target_os = "linux", -    not(target_env = "musl"), -    not(target_arch = "s390x"), -))] -pub type FsWord = c::__fsword_t; - -/// `__fsword_t` -#[cfg(all( -    any(target_os = "android", all(target_os = "linux", target_env = "musl")), -    target_pointer_width = "32", -))] -pub type FsWord = u32; - -/// `__fsword_t` -#[cfg(all( -    any(target_os = "android", all(target_os = "linux", target_env = "musl")), -    not(target_arch = "s390x"), -    target_pointer_width = "64", -))] -pub type FsWord = u64; - -/// `__fsword_t` -// s390x uses `u32` for `statfs` entries on glibc, even though `__fsword_t` is -// `u64`. -#[cfg(all(target_os = "linux", target_arch = "s390x", target_env = "gnu"))] -pub type FsWord = u32; - -/// `__fsword_t` -// s390x uses `u64` for `statfs` entries on musl. -#[cfg(all(target_os = "linux", target_arch = "s390x", target_env = "musl"))] -pub type FsWord = u64; - -/// `copyfile_state_t`—State for use with [`fcopyfile`]. -/// -/// [`fcopyfile`]: crate::fs::fcopyfile -#[cfg(apple)] -#[allow(non_camel_case_types)] -#[repr(transparent)] -#[derive(Copy, Clone)] -pub struct copyfile_state_t(pub(crate) *mut c::c_void);  | 
