@@ -89,6 +89,8 @@ use crate::fs::SealFlags;
89
89
) ) ) ]
90
90
// not implemented in libc for netbsd yet
91
91
use crate :: fs:: StatFs ;
92
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
93
+ use crate :: fs:: { cwd, RenameFlags , ResolveFlags , Statx , StatxFlags } ;
92
94
#[ cfg( not( any(
93
95
target_os = "ios" ,
94
96
target_os = "macos" ,
@@ -97,8 +99,6 @@ use crate::fs::StatFs;
97
99
) ) ) ]
98
100
use crate :: fs:: { Dev , FileType } ;
99
101
use crate :: fs:: { FdFlags , Mode , OFlags , Stat , Timestamps } ;
100
- #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
101
- use crate :: fs:: { RenameFlags , ResolveFlags , Statx , StatxFlags } ;
102
102
use crate :: io:: { self , OwnedFd , SeekFrom } ;
103
103
#[ cfg( not( target_os = "wasi" ) ) ]
104
104
use crate :: process:: { Gid , Uid } ;
@@ -116,18 +116,15 @@ use core::convert::TryInto;
116
116
) ) ]
117
117
use core:: mem:: size_of;
118
118
use core:: mem:: MaybeUninit ;
119
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
120
+ use core:: ptr:: null;
119
121
#[ cfg( any(
120
122
target_os = "android" ,
121
123
target_os = "ios" ,
122
124
target_os = "linux" ,
123
125
target_os = "macos"
124
126
) ) ]
125
127
use core:: ptr:: null_mut;
126
- #[ cfg( all(
127
- any( target_os = "android" , target_os = "linux" ) ,
128
- any( target_pointer_width = "32" , target_arch = "mips64" )
129
- ) ) ]
130
- use core:: sync:: atomic:: { AtomicBool , Ordering :: Relaxed } ;
131
128
#[ cfg( any( target_os = "ios" , target_os = "macos" ) ) ]
132
129
use {
133
130
super :: super :: conv:: nonnegative_ret,
@@ -351,14 +348,11 @@ pub(crate) fn statat(dirfd: BorrowedFd<'_>, path: &CStr, flags: AtFlags) -> io::
351
348
any( target_pointer_width = "32" , target_arch = "mips64" )
352
349
) ) ]
353
350
{
354
- if !NO_STATX . load ( Relaxed ) {
355
- match statx ( dirfd, path, flags, StatxFlags :: BASIC_STATS ) {
356
- Ok ( x) => return statx_to_stat ( x) ,
357
- Err ( io:: Errno :: NOSYS ) => NO_STATX . store ( true , Relaxed ) ,
358
- Err ( e) => return Err ( e) ,
359
- }
351
+ match statx ( dirfd, path, flags, StatxFlags :: BASIC_STATS ) {
352
+ Ok ( x) => return statx_to_stat ( x) ,
353
+ Err ( io:: Errno :: NOSYS ) => statat_old ( dirfd, path, flags) ,
354
+ Err ( e) => return Err ( e) ,
360
355
}
361
- statat_old ( dirfd, path, flags)
362
356
}
363
357
364
358
// Main version: libc is y2038 safe. Or, the platform is not y2038 safe and
@@ -904,13 +898,6 @@ pub(crate) fn flock(fd: BorrowedFd<'_>, operation: FlockOperation) -> io::Result
904
898
unsafe { ret ( c:: flock ( borrowed_fd ( fd) , operation as c:: c_int ) ) }
905
899
}
906
900
907
- /// `statx` was introduced in Linux 4.11.
908
- #[ cfg( all(
909
- any( target_os = "android" , target_os = "linux" ) ,
910
- any( target_pointer_width = "32" , target_arch = "mips64" )
911
- ) ) ]
912
- static NO_STATX : AtomicBool = AtomicBool :: new ( false ) ;
913
-
914
901
pub ( crate ) fn fstat ( fd : BorrowedFd < ' _ > ) -> io:: Result < Stat > {
915
902
// 32-bit and mips64 Linux: `struct stat64` is not y2038 compatible; use
916
903
// `statx`.
@@ -919,14 +906,11 @@ pub(crate) fn fstat(fd: BorrowedFd<'_>) -> io::Result<Stat> {
919
906
any( target_pointer_width = "32" , target_arch = "mips64" )
920
907
) ) ]
921
908
{
922
- if !NO_STATX . load ( Relaxed ) {
923
- match statx ( fd, cstr ! ( "" ) , AtFlags :: EMPTY_PATH , StatxFlags :: BASIC_STATS ) {
924
- Ok ( x) => return statx_to_stat ( x) ,
925
- Err ( io:: Errno :: NOSYS ) => NO_STATX . store ( true , Relaxed ) ,
926
- Err ( e) => return Err ( e) ,
927
- }
909
+ match statx ( fd, cstr ! ( "" ) , AtFlags :: EMPTY_PATH , StatxFlags :: BASIC_STATS ) {
910
+ Ok ( x) => return statx_to_stat ( x) ,
911
+ Err ( io:: Errno :: NOSYS ) => fstat_old ( fd) ,
912
+ Err ( e) => return Err ( e) ,
928
913
}
929
- fstat_old ( fd)
930
914
}
931
915
932
916
// Main version: libc is y2038 safe. Or, the platform is not y2038 safe and
@@ -1398,12 +1382,9 @@ fn stat64_to_stat(s64: c::stat64) -> io::Result<Stat> {
1398
1382
1399
1383
#[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
1400
1384
#[ allow( non_upper_case_globals) ]
1401
- pub ( crate ) fn statx (
1402
- dirfd : BorrowedFd < ' _ > ,
1403
- path : & CStr ,
1404
- flags : AtFlags ,
1405
- mask : StatxFlags ,
1406
- ) -> io:: Result < Statx > {
1385
+ mod sys {
1386
+ use super :: { c, BorrowedFd , Statx } ;
1387
+
1407
1388
#[ cfg( all( target_os = "android" , target_arch = "arm" ) ) ]
1408
1389
const SYS_statx : c:: c_long = 397 ;
1409
1390
#[ cfg( all( target_os = "android" , target_arch = "x86" ) ) ]
@@ -1414,18 +1395,27 @@ pub(crate) fn statx(
1414
1395
const SYS_statx : c:: c_long = 332 ;
1415
1396
1416
1397
weak_or_syscall ! {
1417
- fn statx(
1398
+ pub ( super ) fn statx(
1418
1399
pirfd: BorrowedFd <' _>,
1419
1400
path: * const c:: c_char,
1420
1401
flags: c:: c_int,
1421
1402
mask: c:: c_uint,
1422
1403
buf: * mut Statx
1423
1404
) via SYS_statx -> c:: c_int
1424
1405
}
1406
+ }
1425
1407
1408
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
1409
+ #[ allow( non_upper_case_globals) ]
1410
+ pub ( crate ) fn statx (
1411
+ dirfd : BorrowedFd < ' _ > ,
1412
+ path : & CStr ,
1413
+ flags : AtFlags ,
1414
+ mask : StatxFlags ,
1415
+ ) -> io:: Result < Statx > {
1426
1416
let mut statx_buf = MaybeUninit :: < Statx > :: uninit ( ) ;
1427
1417
unsafe {
1428
- ret ( statx (
1418
+ ret ( sys :: statx (
1429
1419
dirfd,
1430
1420
c_str ( path) ,
1431
1421
flags. bits ( ) ,
@@ -1436,6 +1426,19 @@ pub(crate) fn statx(
1436
1426
}
1437
1427
}
1438
1428
1429
+ #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
1430
+ #[ inline]
1431
+ pub ( crate ) fn is_statx_available ( ) -> bool {
1432
+ unsafe {
1433
+ // Call `statx` with null pointers so that if it fails for any reason
1434
+ // other than `EFAULT`, we know it's not supported.
1435
+ matches ! (
1436
+ ret( sys:: statx( cwd( ) , null( ) , 0 , 0 , null_mut( ) ) ) ,
1437
+ Err ( io:: Errno :: FAULT )
1438
+ )
1439
+ }
1440
+ }
1441
+
1439
1442
#[ cfg( any( target_os = "ios" , target_os = "macos" ) ) ]
1440
1443
pub ( crate ) unsafe fn fcopyfile (
1441
1444
from : BorrowedFd < ' _ > ,
0 commit comments