@@ -83,9 +83,6 @@ use crate::fmt::{self, Write as _};
8383use crate :: fs:: TryLockError ;
8484use crate :: io:: { self , BorrowedCursor , Error , IoSlice , IoSliceMut , SeekFrom } ;
8585use 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" ) ]
9087use 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" ) ) ]
131129pub ( crate ) use cfg_has_statx;
132130
133131cfg_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
532497cfg_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