Skip to content

Commit 2b3a0af

Browse files
authored
Merge pull request #2388 from djones6/fallback_on_statx_eperm
Fallback if statx syscall is not permitted
2 parents d643057 + 2ca91c9 commit 2b3a0af

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -538,20 +538,21 @@ static inline unsigned int _dev_minor(dev_t rdev) {
538538

539539
// There is no glibc statx() function, it must be called using syscall().
540540

541-
static inline ssize_t
541+
static inline int
542542
_statx(int dfd, const char *filename, unsigned int flags, unsigned int mask, struct statx *buffer) {
543-
return syscall(__NR_statx, dfd, filename, flags, mask, buffer);
543+
int ret = syscall(__NR_statx, dfd, filename, flags, mask, buffer);
544+
return ret == 0 ? ret : errno;
544545
}
545546

546547
// At the moment the only extra information statx() is used for is to get the btime (file creation time).
547548
// This function is here instead of in FileManager.swift because there is no way of setting a conditional
548549
// define that could be used with a #if in the Swift code.
549-
static inline ssize_t
550+
static inline int
550551
_stat_with_btime(const char *filename, struct stat *buffer, struct timespec *btime) {
551552
struct statx statx_buffer = {0};
552553
*btime = (struct timespec) {0};
553554

554-
ssize_t ret = _statx(AT_FDCWD, filename, AT_SYMLINK_NOFOLLOW | AT_STATX_SYNC_AS_STAT, STATX_ALL, &statx_buffer);
555+
int ret = _statx(AT_FDCWD, filename, AT_SYMLINK_NOFOLLOW | AT_STATX_SYNC_AS_STAT, STATX_ALL, &statx_buffer);
555556
if (ret == 0) {
556557
*buffer = (struct stat) {
557558
.st_dev = makedev(statx_buffer.stx_dev_major, statx_buffer.stx_dev_minor),
@@ -587,10 +588,10 @@ _stat_with_btime(const char *filename, struct stat *buffer, struct timespec *bti
587588

588589
// Dummy version when compiled where struct statx is not defined in the headers.
589590
// Just calles lstat() instead.
590-
static inline ssize_t
591+
static inline int
591592
_stat_with_btime(const char *filename, struct stat *buffer, struct timespec *btime) {
592593
*btime = (struct timespec) {0};
593-
return lstat(filename, buffer);
594+
return lstat(filename, buffer) == 0 ? 0 : errno;
594595
}
595596
#endif // __NR_statx
596597

Foundation/FileManager+POSIX.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -927,13 +927,24 @@ extension FileManager {
927927
// structure and optional creation date.
928928

929929
internal func _statxFile(atPath path: String) throws -> (stat, Date?) {
930-
return try _fileSystemRepresentation(withPath: path) { fsRep in
930+
// Fallback if statx() is unavailable or fails
931+
func _statxFallback(atPath path: String, withFileSystemRepresentation fsRep: UnsafePointer<Int8>?) throws -> (stat, Date?) {
932+
let statInfo = try _lstatFile(atPath: path, withFileSystemRepresentation: fsRep)
933+
return (statInfo, nil)
934+
}
931935

936+
return try _fileSystemRepresentation(withPath: path) { fsRep in
932937
if supportsStatx {
933938
var statInfo = stat()
934939
var btime = timespec()
935-
guard _stat_with_btime(fsRep, &statInfo, &btime) == 0 else {
936-
throw _NSErrorWithErrno(errno, reading: true, path: path)
940+
let statxErrno = _stat_with_btime(fsRep, &statInfo, &btime)
941+
guard statxErrno == 0 else {
942+
switch statxErrno {
943+
case EPERM:
944+
return try _statxFallback(atPath: path, withFileSystemRepresentation: fsRep)
945+
default:
946+
throw _NSErrorWithErrno(statxErrno, reading: true, path: path)
947+
}
937948
}
938949

939950
let sec = btime.tv_sec
@@ -947,9 +958,7 @@ extension FileManager {
947958
}
948959
return (statInfo, creationDate)
949960
} else {
950-
// fallback if statx() is unavailable or fails
951-
let statInfo = try _lstatFile(atPath: path, withFileSystemRepresentation: fsRep)
952-
return (statInfo, nil)
961+
return try _statxFallback(atPath: path, withFileSystemRepresentation: fsRep)
953962
}
954963
}
955964
}

0 commit comments

Comments
 (0)