aboutsummaryrefslogtreecommitdiff
path: root/vendor/rustix/src/backend/libc/fs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/src/backend/libc/fs')
-rw-r--r--vendor/rustix/src/backend/libc/fs/dir.rs423
-rw-r--r--vendor/rustix/src/backend/libc/fs/inotify.rs131
-rw-r--r--vendor/rustix/src/backend/libc/fs/makedev.rs138
-rw-r--r--vendor/rustix/src/backend/libc/fs/mod.rs23
-rw-r--r--vendor/rustix/src/backend/libc/fs/syscalls.rs2514
-rw-r--r--vendor/rustix/src/backend/libc/fs/types.rs1164
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(&times).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(&times).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);