Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganize Stat, Statx, and SockaddrStorage #1282

Merged
merged 20 commits into from
Jan 30, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/backend/libc/c.rs
Original file line number Diff line number Diff line change
@@ -483,3 +483,33 @@ mod readwrite_pv64v2 {
all(target_os = "linux", not(target_env = "gnu")),
))]
pub(super) use readwrite_pv64v2::{preadv64v2 as preadv2, pwritev64v2 as pwritev2};

// Rust's libc crate lacks statx for Non-glibc targets.
#[cfg(feature = "fs")]
#[cfg(all(
linux_like,
not(any(target_os = "android", target_os = "emscripten", target_env = "gnu"))
))]
mod statx_flags {
pub(crate) use linux_raw_sys::general::{
STATX_ALL, STATX_ATIME, STATX_BASIC_STATS, STATX_BLOCKS, STATX_BTIME, STATX_CTIME,
STATX_DIOALIGN, STATX_GID, STATX_INO, STATX_MNT_ID, STATX_MODE, STATX_MTIME, STATX_NLINK,
STATX_SIZE, STATX_TYPE, STATX_UID,
};

pub(crate) use linux_raw_sys::general::{
STATX_ATTR_APPEND, STATX_ATTR_AUTOMOUNT, STATX_ATTR_COMPRESSED, STATX_ATTR_DAX,
STATX_ATTR_ENCRYPTED, STATX_ATTR_IMMUTABLE, STATX_ATTR_MOUNT_ROOT, STATX_ATTR_NODUMP,
STATX_ATTR_VERITY,
};
}
#[cfg(feature = "fs")]
#[cfg(all(
linux_like,
not(any(target_os = "android", target_os = "emscripten", target_env = "gnu"))
))]
pub(crate) use statx_flags::*;

#[cfg(feature = "fs")]
#[cfg(target_os = "android")]
pub(crate) use libc::__fsid_t as fsid_t;
199 changes: 11 additions & 188 deletions src/backend/libc/fs/types.rs
Original file line number Diff line number Diff line change
@@ -674,128 +674,6 @@ bitflags! {
}
}

#[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,
target_os = "espidf",
@@ -1022,13 +900,12 @@ pub type Stat = c::stat64;
// 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_nlink: u64,
pub st_uid: u32,
pub st_gid: u32,
pub st_rdev: u64,
@@ -1069,6 +946,16 @@ pub type StatFs = c::statfs;
#[cfg(linux_like)]
pub type StatFs = c::statfs64;

/// `fsid_t` for use with `StatFs`.
#[cfg(not(any(
solarish,
target_os = "haiku",
target_os = "nto",
target_os = "redox",
target_os = "wasi"
)))]
pub type Fsid = c::fsid_t;

/// `struct statvfs` for use with [`statvfs`] and [`fstatvfs`].
///
/// [`statvfs`]: crate::fs::statvfs
@@ -1089,70 +976,6 @@ pub struct StatVfs {
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;
2 changes: 1 addition & 1 deletion src/backend/libc/io/errno.rs
Original file line number Diff line number Diff line change
@@ -782,7 +782,7 @@ impl Errno {
#[cfg(not(target_os = "l4re"))]
pub const NOTSOCK: Self = Self(c::ENOTSOCK);
/// `ENOTSUP`
#[cfg(not(any(windows, target_os = "haiku", target_os = "redox")))]
#[cfg(not(any(windows, target_os = "redox")))]
pub const NOTSUP: Self = Self(c::ENOTSUP);
/// `ENOTTY`
#[cfg(not(windows))]
48 changes: 45 additions & 3 deletions src/backend/libc/net/addr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! Socket address utilities.

use crate::backend::c;
use crate::net::AddressFamily;
use core::mem::size_of;
use core::slice;
#[cfg(unix)]
use {
crate::ffi::CStr,
@@ -9,7 +12,6 @@ use {
core::cmp::Ordering,
core::fmt,
core::hash::{Hash, Hasher},
core::slice,
};

/// `struct sockaddr_un`
@@ -208,8 +210,48 @@ impl fmt::Debug for SocketAddrUnix {
}
}

/// `struct sockaddr_storage` as a raw struct.
pub type SocketAddrStorage = c::sockaddr_storage;
/// `struct sockaddr_storage`.
#[repr(transparent)]
pub struct SocketAddrStorage(c::sockaddr_storage);

impl SocketAddrStorage {
/// Return a socket addr storage initialized to all zero bytes. The
/// `sa_family` is set to `AddressFamily::UNSPEC`.
pub fn zeroed() -> Self {
assert_eq!(c::AF_UNSPEC, 0);
// SAFETY: `sockaddr_storage` is meant to be zero-initializable.
unsafe { core::mem::zeroed() }
}

/// Return the `sa_family` of this socket address.
pub fn family(&self) -> AddressFamily {
unsafe {
AddressFamily::from_raw(crate::backend::net::read_sockaddr::read_sa_family(
crate::utils::as_ptr(&self.0).cast::<c::sockaddr>(),
))
}
}

/// Clear the `sa_family` of this socket address to
/// `AddressFamily::UNSPEC`.
pub fn clear_family(&mut self) {
unsafe {
crate::backend::net::read_sockaddr::initialize_family_to_unspec(
crate::utils::as_mut_ptr(&mut self.0).cast::<c::sockaddr>(),
)
}
}

/// View the storage as a byte slice.
pub fn as_mut_bytes(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(
crate::utils::as_mut_ptr(self).cast::<u8>(),
size_of::<Self>(),
)
}
}
}

/// Return the offset of the `sun_path` field of `sockaddr_un`.
#[cfg(not(windows))]
Loading