Skip to content

Commit 7202da6

Browse files
authored
Reorganize Stat, Statx, and SockaddrStorage (#1282)
* Reorganize Stat, Statx, and SockaddrStorage Remove linux-raw-sys types for `stat`, `statx`, and `__kernel_sockaddr_storage` from the public API. To do this, define our own `Statx` struct. This also enables moving `stx_attributes` to a bitflags type. * Fix a test to clean up its "yes" processes. * Add a `stat` test. * Make a `__reserved` field `pub(crate)`. * Add ways to read or clear the `sa_family` from a `SocketAddrStorage`. Also, say "sa_family" instead of "ss_family" in most places. * Add accessors to `SockaddrStorage` for accessing the storage.
1 parent e231b42 commit 7202da6

23 files changed

Lines changed: 810 additions & 367 deletions

src/backend/libc/c.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,3 +483,33 @@ mod readwrite_pv64v2 {
483483
all(target_os = "linux", not(target_env = "gnu")),
484484
))]
485485
pub(super) use readwrite_pv64v2::{preadv64v2 as preadv2, pwritev64v2 as pwritev2};
486+
487+
// Rust's libc crate lacks statx for Non-glibc targets.
488+
#[cfg(feature = "fs")]
489+
#[cfg(all(
490+
linux_like,
491+
not(any(target_os = "android", target_os = "emscripten", target_env = "gnu"))
492+
))]
493+
mod statx_flags {
494+
pub(crate) use linux_raw_sys::general::{
495+
STATX_ALL, STATX_ATIME, STATX_BASIC_STATS, STATX_BLOCKS, STATX_BTIME, STATX_CTIME,
496+
STATX_DIOALIGN, STATX_GID, STATX_INO, STATX_MNT_ID, STATX_MODE, STATX_MTIME, STATX_NLINK,
497+
STATX_SIZE, STATX_TYPE, STATX_UID,
498+
};
499+
500+
pub(crate) use linux_raw_sys::general::{
501+
STATX_ATTR_APPEND, STATX_ATTR_AUTOMOUNT, STATX_ATTR_COMPRESSED, STATX_ATTR_DAX,
502+
STATX_ATTR_ENCRYPTED, STATX_ATTR_IMMUTABLE, STATX_ATTR_MOUNT_ROOT, STATX_ATTR_NODUMP,
503+
STATX_ATTR_VERITY,
504+
};
505+
}
506+
#[cfg(feature = "fs")]
507+
#[cfg(all(
508+
linux_like,
509+
not(any(target_os = "android", target_os = "emscripten", target_env = "gnu"))
510+
))]
511+
pub(crate) use statx_flags::*;
512+
513+
#[cfg(feature = "fs")]
514+
#[cfg(target_os = "android")]
515+
pub(crate) use libc::__fsid_t as fsid_t;

src/backend/libc/fs/types.rs

Lines changed: 11 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -674,128 +674,6 @@ bitflags! {
674674
}
675675
}
676676

677-
#[cfg(all(target_os = "linux", target_env = "gnu"))]
678-
bitflags! {
679-
/// `STATX_*` constants for use with [`statx`].
680-
///
681-
/// [`statx`]: crate::fs::statx
682-
#[repr(transparent)]
683-
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
684-
pub struct StatxFlags: u32 {
685-
/// `STATX_TYPE`
686-
const TYPE = c::STATX_TYPE;
687-
688-
/// `STATX_MODE`
689-
const MODE = c::STATX_MODE;
690-
691-
/// `STATX_NLINK`
692-
const NLINK = c::STATX_NLINK;
693-
694-
/// `STATX_UID`
695-
const UID = c::STATX_UID;
696-
697-
/// `STATX_GID`
698-
const GID = c::STATX_GID;
699-
700-
/// `STATX_ATIME`
701-
const ATIME = c::STATX_ATIME;
702-
703-
/// `STATX_MTIME`
704-
const MTIME = c::STATX_MTIME;
705-
706-
/// `STATX_CTIME`
707-
const CTIME = c::STATX_CTIME;
708-
709-
/// `STATX_INO`
710-
const INO = c::STATX_INO;
711-
712-
/// `STATX_SIZE`
713-
const SIZE = c::STATX_SIZE;
714-
715-
/// `STATX_BLOCKS`
716-
const BLOCKS = c::STATX_BLOCKS;
717-
718-
/// `STATX_BASIC_STATS`
719-
const BASIC_STATS = c::STATX_BASIC_STATS;
720-
721-
/// `STATX_BTIME`
722-
const BTIME = c::STATX_BTIME;
723-
724-
/// `STATX_MNT_ID` (since Linux 5.8)
725-
const MNT_ID = c::STATX_MNT_ID;
726-
727-
/// `STATX_DIOALIGN` (since Linux 6.1)
728-
const DIOALIGN = c::STATX_DIOALIGN;
729-
730-
/// `STATX_ALL`
731-
const ALL = c::STATX_ALL;
732-
733-
/// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
734-
const _ = !0;
735-
}
736-
}
737-
738-
#[cfg(any(
739-
target_os = "android",
740-
all(target_os = "linux", not(target_env = "gnu")),
741-
))]
742-
bitflags! {
743-
/// `STATX_*` constants for use with [`statx`].
744-
///
745-
/// [`statx`]: crate::fs::statx
746-
#[repr(transparent)]
747-
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
748-
pub struct StatxFlags: u32 {
749-
/// `STATX_TYPE`
750-
const TYPE = 0x0001;
751-
752-
/// `STATX_MODE`
753-
const MODE = 0x0002;
754-
755-
/// `STATX_NLINK`
756-
const NLINK = 0x0004;
757-
758-
/// `STATX_UID`
759-
const UID = 0x0008;
760-
761-
/// `STATX_GID`
762-
const GID = 0x0010;
763-
764-
/// `STATX_ATIME`
765-
const ATIME = 0x0020;
766-
767-
/// `STATX_MTIME`
768-
const MTIME = 0x0040;
769-
770-
/// `STATX_CTIME`
771-
const CTIME = 0x0080;
772-
773-
/// `STATX_INO`
774-
const INO = 0x0100;
775-
776-
/// `STATX_SIZE`
777-
const SIZE = 0x0200;
778-
779-
/// `STATX_BLOCKS`
780-
const BLOCKS = 0x0400;
781-
782-
/// `STATX_BASIC_STATS`
783-
const BASIC_STATS = 0x07ff;
784-
785-
/// `STATX_BTIME`
786-
const BTIME = 0x800;
787-
788-
/// `STATX_MNT_ID` (since Linux 5.8)
789-
const MNT_ID = 0x1000;
790-
791-
/// `STATX_ALL`
792-
const ALL = 0xfff;
793-
794-
/// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
795-
const _ = !0;
796-
}
797-
}
798-
799677
#[cfg(not(any(
800678
netbsdlike,
801679
target_os = "espidf",
@@ -1022,13 +900,12 @@ pub type Stat = c::stat64;
1022900
// we use our own struct, populated from `statx` where possible, to avoid the
1023901
// y2038 bug.
1024902
#[cfg(all(linux_kernel, target_pointer_width = "32"))]
1025-
#[repr(C)]
1026903
#[derive(Debug, Copy, Clone)]
1027904
#[allow(missing_docs)]
1028905
pub struct Stat {
1029906
pub st_dev: u64,
1030907
pub st_mode: u32,
1031-
pub st_nlink: u32,
908+
pub st_nlink: u64,
1032909
pub st_uid: u32,
1033910
pub st_gid: u32,
1034911
pub st_rdev: u64,
@@ -1069,6 +946,16 @@ pub type StatFs = c::statfs;
1069946
#[cfg(linux_like)]
1070947
pub type StatFs = c::statfs64;
1071948

949+
/// `fsid_t` for use with `StatFs`.
950+
#[cfg(not(any(
951+
solarish,
952+
target_os = "haiku",
953+
target_os = "nto",
954+
target_os = "redox",
955+
target_os = "wasi"
956+
)))]
957+
pub type Fsid = c::fsid_t;
958+
1072959
/// `struct statvfs` for use with [`statvfs`] and [`fstatvfs`].
1073960
///
1074961
/// [`statvfs`]: crate::fs::statvfs
@@ -1089,70 +976,6 @@ pub struct StatVfs {
1089976
pub f_namemax: u64,
1090977
}
1091978

1092-
/// `struct statx` for use with [`statx`].
1093-
///
1094-
/// [`statx`]: crate::fs::statx
1095-
#[cfg(all(target_os = "linux", target_env = "gnu"))]
1096-
// Use the glibc `struct statx`.
1097-
pub type Statx = c::statx;
1098-
1099-
/// `struct statx_timestamp` for use with [`Statx`].
1100-
#[cfg(all(target_os = "linux", target_env = "gnu"))]
1101-
// Use the glibc `struct statx_timestamp`.
1102-
pub type StatxTimestamp = c::statx;
1103-
1104-
/// `struct statx` for use with [`statx`].
1105-
///
1106-
/// [`statx`]: crate::fs::statx
1107-
// Non-glibc ABIs don't currently declare a `struct statx`, so we declare it
1108-
// ourselves.
1109-
#[cfg(any(
1110-
target_os = "android",
1111-
all(target_os = "linux", not(target_env = "gnu")),
1112-
))]
1113-
#[repr(C)]
1114-
#[allow(missing_docs)]
1115-
pub struct Statx {
1116-
pub stx_mask: u32,
1117-
pub stx_blksize: u32,
1118-
pub stx_attributes: u64,
1119-
pub stx_nlink: u32,
1120-
pub stx_uid: u32,
1121-
pub stx_gid: u32,
1122-
pub stx_mode: u16,
1123-
__statx_pad1: [u16; 1],
1124-
pub stx_ino: u64,
1125-
pub stx_size: u64,
1126-
pub stx_blocks: u64,
1127-
pub stx_attributes_mask: u64,
1128-
pub stx_atime: StatxTimestamp,
1129-
pub stx_btime: StatxTimestamp,
1130-
pub stx_ctime: StatxTimestamp,
1131-
pub stx_mtime: StatxTimestamp,
1132-
pub stx_rdev_major: u32,
1133-
pub stx_rdev_minor: u32,
1134-
pub stx_dev_major: u32,
1135-
pub stx_dev_minor: u32,
1136-
pub stx_mnt_id: u64,
1137-
__statx_pad2: u64,
1138-
__statx_pad3: [u64; 12],
1139-
}
1140-
1141-
/// `struct statx_timestamp` for use with [`Statx`].
1142-
// Non-glibc ABIs don't currently declare a `struct statx_timestamp`, so we
1143-
// declare it ourselves.
1144-
#[cfg(any(
1145-
target_os = "android",
1146-
all(target_os = "linux", not(target_env = "gnu")),
1147-
))]
1148-
#[repr(C)]
1149-
#[allow(missing_docs)]
1150-
pub struct StatxTimestamp {
1151-
pub tv_sec: i64,
1152-
pub tv_nsec: u32,
1153-
pub __statx_timestamp_pad1: [i32; 1],
1154-
}
1155-
1156979
/// `mode_t`
1157980
#[cfg(not(all(target_os = "android", target_pointer_width = "32")))]
1158981
pub type RawMode = c::mode_t;

src/backend/libc/io/errno.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ impl Errno {
782782
#[cfg(not(target_os = "l4re"))]
783783
pub const NOTSOCK: Self = Self(c::ENOTSOCK);
784784
/// `ENOTSUP`
785-
#[cfg(not(any(windows, target_os = "haiku", target_os = "redox")))]
785+
#[cfg(not(any(windows, target_os = "redox")))]
786786
pub const NOTSUP: Self = Self(c::ENOTSUP);
787787
/// `ENOTTY`
788788
#[cfg(not(windows))]

src/backend/libc/net/addr.rs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
//! Socket address utilities.
22
33
use crate::backend::c;
4+
use crate::net::AddressFamily;
5+
use core::mem::size_of;
6+
use core::slice;
47
#[cfg(unix)]
58
use {
69
crate::ffi::CStr,
@@ -9,7 +12,6 @@ use {
912
core::cmp::Ordering,
1013
core::fmt,
1114
core::hash::{Hash, Hasher},
12-
core::slice,
1315
};
1416

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

211-
/// `struct sockaddr_storage` as a raw struct.
212-
pub type SocketAddrStorage = c::sockaddr_storage;
213+
/// `struct sockaddr_storage`.
214+
#[repr(transparent)]
215+
pub struct SocketAddrStorage(c::sockaddr_storage);
216+
217+
impl SocketAddrStorage {
218+
/// Return a socket addr storage initialized to all zero bytes. The
219+
/// `sa_family` is set to `AddressFamily::UNSPEC`.
220+
pub fn zeroed() -> Self {
221+
assert_eq!(c::AF_UNSPEC, 0);
222+
// SAFETY: `sockaddr_storage` is meant to be zero-initializable.
223+
unsafe { core::mem::zeroed() }
224+
}
225+
226+
/// Return the `sa_family` of this socket address.
227+
pub fn family(&self) -> AddressFamily {
228+
unsafe {
229+
AddressFamily::from_raw(crate::backend::net::read_sockaddr::read_sa_family(
230+
crate::utils::as_ptr(&self.0).cast::<c::sockaddr>(),
231+
))
232+
}
233+
}
234+
235+
/// Clear the `sa_family` of this socket address to
236+
/// `AddressFamily::UNSPEC`.
237+
pub fn clear_family(&mut self) {
238+
unsafe {
239+
crate::backend::net::read_sockaddr::initialize_family_to_unspec(
240+
crate::utils::as_mut_ptr(&mut self.0).cast::<c::sockaddr>(),
241+
)
242+
}
243+
}
244+
245+
/// View the storage as a byte slice.
246+
pub fn as_mut_bytes(&mut self) -> &mut [u8] {
247+
unsafe {
248+
slice::from_raw_parts_mut(
249+
crate::utils::as_mut_ptr(self).cast::<u8>(),
250+
size_of::<Self>(),
251+
)
252+
}
253+
}
254+
}
213255

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

0 commit comments

Comments
 (0)