Skip to content

Commit 66913d2

Browse files
committed
Refactored shared code from try_statx and Metadata::from_statx into a function with FileAttr::from_statx
1 parent c892c41 commit 66913d2

3 files changed

Lines changed: 48 additions & 79 deletions

File tree

library/std/src/os/linux/fs.rs

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@
44
55
#![stable(feature = "metadata_ext", since = "1.1.0")]
66

7-
use core::mem;
8-
97
use crate::fs::Metadata;
108
#[allow(deprecated)]
119
use crate::os::linux::raw;
1210
use crate::os::raw::{c_uint, c_void};
1311
use crate::sys::AsInner;
1412
use crate::sys::fs::cfg_has_statx;
1513
cfg_has_statx! {{
16-
use crate::sys::fs::{FileAttr, StatxExtraFields};
14+
use crate::sys::fs::FileAttr;
1715
use crate::sys::FromInner;
1816
} else {
1917
use crate::sys::unsupported;
@@ -405,32 +403,7 @@ impl MetadataExt for Metadata {
405403
}
406404
cfg_has_statx! {{
407405
unsafe fn from_statx(statxbuf: *const c_void) -> Metadata {
408-
let buf = statxbuf as *const libc::statx;
409-
410-
// We cannot fill `stat64` exhaustively because of private padding fields.
411-
let mut stat: libc::stat64 = mem::zeroed();
412-
// `c_ulong` on gnu-mips, `dev_t` otherwise
413-
stat.st_dev = libc::makedev((*buf).stx_dev_major, (*buf).stx_dev_minor) as _;
414-
stat.st_ino = (*buf).stx_ino as libc::ino64_t;
415-
stat.st_nlink = (*buf).stx_nlink as libc::nlink_t;
416-
stat.st_mode = (*buf).stx_mode as libc::mode_t;
417-
stat.st_uid = (*buf).stx_uid as libc::uid_t;
418-
stat.st_gid = (*buf).stx_gid as libc::gid_t;
419-
stat.st_rdev = libc::makedev((*buf).stx_rdev_major, (*buf).stx_rdev_minor) as _;
420-
stat.st_size = (*buf).stx_size as libc::off64_t;
421-
stat.st_blksize = (*buf).stx_blksize as libc::blksize_t;
422-
stat.st_blocks = (*buf).stx_blocks as libc::blkcnt64_t;
423-
stat.st_atime = (*buf).stx_atime.tv_sec as libc::time_t;
424-
// `i64` on gnu-x86_64-x32, `c_ulong` otherwise.
425-
stat.st_atime_nsec = (*buf).stx_atime.tv_nsec as _;
426-
stat.st_mtime = (*buf).stx_mtime.tv_sec as libc::time_t;
427-
stat.st_mtime_nsec = (*buf).stx_mtime.tv_nsec as _;
428-
stat.st_ctime = (*buf).stx_ctime.tv_sec as libc::time_t;
429-
stat.st_ctime_nsec = (*buf).stx_ctime.tv_nsec as _;
430-
431-
let extra = StatxExtraFields::from_statx(statxbuf);
432-
433-
Metadata::from_inner(FileAttr::from_statx(stat, Some(extra)))
406+
Metadata::from_inner(FileAttr::from_statx(*(statxbuf as *const libc::statx)))
434407
}} else {
435408
unsafe fn from_statx(statxbuf: *const c_void) -> Self {
436409
unsupported();

library/std/src/sys/fs/mod.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ cfg_select! {
1919
pub(super) use unix::CachedFileMetadata;
2020
use crate::sys::helpers::run_path_with_cstr as with_native_path;
2121
#[cfg(all(target_os = "linux", target_env = "gnu"))]
22-
pub(crate) use unix::{
23-
cfg_has_statx, StatxExtraFields
24-
};
22+
pub(crate) use unix::cfg_has_statx;
2523
}
2624
target_os = "windows" => {
2725
mod windows;

library/std/src/sys/fs/unix.rs

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,6 @@ use crate::fmt::{self, Write as _};
8383
use crate::fs::TryLockError;
8484
use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
8585
use crate::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd};
86-
cfg_has_statx! {{
87-
use crate::os::raw::c_void;
88-
} else {}}
8986
#[cfg(target_family = "unix")]
9087
use crate::os::unix::prelude::*;
9188
#[cfg(target_os = "wasi")]
@@ -128,6 +125,7 @@ macro_rules! cfg_has_statx {
128125
};
129126
}
130127

128+
#[cfg(all(target_os = "linux", target_env = "gnu"))]
131129
pub(crate) use cfg_has_statx;
132130

133131
cfg_has_statx! {{
@@ -217,40 +215,7 @@ cfg_has_statx! {{
217215
STATX_SAVED_STATE.store(STATX_STATE::Present as u8, Ordering::Relaxed);
218216
}
219217

220-
// We cannot fill `stat64` exhaustively because of private padding fields.
221-
let mut stat: stat64 = mem::zeroed();
222-
// `c_ulong` on gnu-mips, `dev_t` otherwise
223-
stat.st_dev = libc::makedev(buf.stx_dev_major, buf.stx_dev_minor) as _;
224-
stat.st_ino = buf.stx_ino as libc::ino64_t;
225-
stat.st_nlink = buf.stx_nlink as libc::nlink_t;
226-
stat.st_mode = buf.stx_mode as libc::mode_t;
227-
stat.st_uid = buf.stx_uid as libc::uid_t;
228-
stat.st_gid = buf.stx_gid as libc::gid_t;
229-
stat.st_rdev = libc::makedev(buf.stx_rdev_major, buf.stx_rdev_minor) as _;
230-
stat.st_size = buf.stx_size as off64_t;
231-
stat.st_blksize = buf.stx_blksize as libc::blksize_t;
232-
stat.st_blocks = buf.stx_blocks as libc::blkcnt64_t;
233-
stat.st_atime = buf.stx_atime.tv_sec as libc::time_t;
234-
// `i64` on gnu-x86_64-x32, `c_ulong` otherwise.
235-
stat.st_atime_nsec = buf.stx_atime.tv_nsec as _;
236-
stat.st_mtime = buf.stx_mtime.tv_sec as libc::time_t;
237-
stat.st_mtime_nsec = buf.stx_mtime.tv_nsec as _;
238-
stat.st_ctime = buf.stx_ctime.tv_sec as libc::time_t;
239-
stat.st_ctime_nsec = buf.stx_ctime.tv_nsec as _;
240-
241-
let extra = StatxExtraFields {
242-
stx_mask: buf.stx_mask,
243-
stx_btime: buf.stx_btime,
244-
// Store full times to avoid 32-bit `time_t` truncation.
245-
#[cfg(target_pointer_width = "32")]
246-
stx_atime: buf.stx_atime,
247-
#[cfg(target_pointer_width = "32")]
248-
stx_ctime: buf.stx_ctime,
249-
#[cfg(target_pointer_width = "32")]
250-
stx_mtime: buf.stx_mtime,
251-
};
252-
253-
Some(Ok(FileAttr { stat, statx_extra_fields: Some(extra) }))
218+
Some(Ok(FileAttr::from_statx(buf)))
254219
}
255220

256221
} else {
@@ -531,19 +496,23 @@ struct Mode(mode_t);
531496

532497
cfg_has_statx! {{
533498
impl StatxExtraFields {
534-
pub unsafe fn from_statx(statxbuf: *const c_void) -> Self {
535-
let buf = statxbuf as *const libc::statx;
536-
499+
/// Constructs `StatxExtraFields` from a given `libc::statx` struct
500+
///
501+
/// SAFETY:
502+
/// The caller must take care to provide a `libc::statx` buffer that is
503+
/// populated by the statx syscall with the flags `STATX_BASIC_STATS`
504+
/// and `STATX_BTIME` enabled
505+
pub unsafe fn from_statx(buf: libc::statx) -> Self {
537506
StatxExtraFields {
538-
stx_mask: (*buf).stx_mask,
539-
stx_btime: (*buf).stx_btime,
507+
stx_mask: buf.stx_mask,
508+
stx_btime: buf.stx_btime,
540509
// Store full times to avoid 32-bit `time_t` truncation.
541510
#[cfg(target_pointer_width = "32")]
542-
stx_atime: (*buf).stx_atime,
511+
stx_atime: buf.stx_atime,
543512
#[cfg(target_pointer_width = "32")]
544-
stx_ctime: (*buf).stx_ctime,
513+
stx_ctime: buf.stx_ctime,
545514
#[cfg(target_pointer_width = "32")]
546-
stx_mtime: (*buf).stx_mtime,
515+
stx_mtime: buf.stx_mtime,
547516
}
548517
}
549518
}
@@ -552,8 +521,37 @@ cfg_has_statx! {{
552521
Self { stat, statx_extra_fields: None }
553522
}
554523

555-
pub fn from_statx(stat: stat64, extra: Option<StatxExtraFields>) -> Self {
556-
Self {stat, statx_extra_fields: extra}
524+
/// Constructs `FileAttr` from a given `libc::statx` struct
525+
///
526+
/// SAFETY:
527+
/// The caller must take care to provide a `libc::statx` buffer that is
528+
/// populated by the statx syscall with the flags `STATX_BASIC_STATS`
529+
/// and `STATX_BTIME` enabled
530+
pub unsafe fn from_statx(buf: libc::statx) -> Self {
531+
// We cannot fill `stat64` exhaustively because of private padding fields.
532+
let mut stat: libc::stat64 = mem::zeroed();
533+
// `c_ulong` on gnu-mips, `dev_t` otherwise
534+
stat.st_dev = libc::makedev((buf).stx_dev_major, (buf).stx_dev_minor) as _;
535+
stat.st_ino = buf.stx_ino as libc::ino64_t;
536+
stat.st_nlink = buf.stx_nlink as libc::nlink_t;
537+
stat.st_mode = buf.stx_mode as libc::mode_t;
538+
stat.st_uid = buf.stx_uid as libc::uid_t;
539+
stat.st_gid = buf.stx_gid as libc::gid_t;
540+
stat.st_rdev = libc::makedev(buf.stx_rdev_major, buf.stx_rdev_minor) as _;
541+
stat.st_size = buf.stx_size as libc::off64_t;
542+
stat.st_blksize = buf.stx_blksize as libc::blksize_t;
543+
stat.st_blocks = buf.stx_blocks as libc::blkcnt64_t;
544+
stat.st_atime = buf.stx_atime.tv_sec as libc::time_t;
545+
// `i64` on gnu-x86_64-x32, `c_ulong` otherwise.
546+
stat.st_atime_nsec = buf.stx_atime.tv_nsec as _;
547+
stat.st_mtime = buf.stx_mtime.tv_sec as libc::time_t;
548+
stat.st_mtime_nsec = buf.stx_mtime.tv_nsec as _;
549+
stat.st_ctime = buf.stx_ctime.tv_sec as libc::time_t;
550+
stat.st_ctime_nsec = buf.stx_ctime.tv_nsec as _;
551+
552+
let statx_extra_fields = Some(StatxExtraFields::from_statx(buf));
553+
554+
Self {stat, statx_extra_fields}
557555
}
558556

559557
#[cfg(target_pointer_width = "32")]

0 commit comments

Comments
 (0)