Skip to content

Commit 5bf53d2

Browse files
committed
Build the new FileSystem module for Android
Motivation: Get the new module building and tested on my Android CI again Modifications: - Add force unwraps where needed - Update C types and account for nullability annotations in NDK 26 - Invoke Foundation in the tests instead of /tmp directly - Don't copy over extended attributes Result: Everything works again on Android
1 parent 8a9a3b1 commit 5bf53d2

File tree

10 files changed

+46
-11
lines changed

10 files changed

+46
-11
lines changed

Sources/NIOFileSystem/DirectoryEntries.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ private struct DirectoryEnumerator: Sendable {
650650

651651
extension UnsafeMutablePointer<CInterop.FTSEnt> {
652652
fileprivate var path: FilePath {
653-
return FilePath(platformString: self.pointee.fts_path)
653+
return FilePath(platformString: self.pointee.fts_path!)
654654
}
655655
}
656656

Sources/NIOFileSystem/FileInfo.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ public struct FileInfo: Hashable, Sendable {
7373
/// Creates a ``FileInfo`` by deriving values from a platform-specific value.
7474
public init(platformSpecificStatus: CInterop.Stat) {
7575
self._platformSpecificStatus = Stat(platformSpecificStatus)
76-
self.type = FileType(platformSpecificMode: platformSpecificStatus.st_mode)
77-
self.permissions = FilePermissions(masking: platformSpecificStatus.st_mode)
76+
self.type = FileType(platformSpecificMode: CInterop.Mode(platformSpecificStatus.st_mode))
77+
self.permissions = FilePermissions(masking: CInterop.Mode(platformSpecificStatus.st_mode))
7878
self.size = Int64(platformSpecificStatus.st_size)
7979
self.userID = UserID(rawValue: platformSpecificStatus.st_uid)
8080
self.groupID = GroupID(rawValue: platformSpecificStatus.st_gid)

Sources/NIOFileSystem/FileSystem.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,7 @@ extension FileSystem {
959959
permissions: info.permissions
960960
)
961961

962+
#if !os(Android)
962963
// Copy over extended attributes, if any exist.
963964
do {
964965
let attributes = try await dir.attributeNames()
@@ -979,6 +980,7 @@ extension FileSystem {
979980
// that is the case.
980981
()
981982
}
983+
#endif
982984

983985
// Build a list of directories to copy over. Do this after closing the current
984986
// directory to avoid using too many descriptors.

Sources/NIOFileSystem/FileType.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ extension FileType {
136136
/// Initializes a file type from the `d_type` from `dirent`.
137137
@_spi(Testing)
138138
public init(direntType: UInt8) {
139-
#if canImport(Darwin) || canImport(Musl)
139+
#if canImport(Darwin) || canImport(Musl) || os(Android)
140140
let value = Int32(direntType)
141141
#elseif canImport(Glibc)
142142
let value = Int(direntType)

Sources/NIOFileSystem/Internal/Concurrency Primitives/ThreadPosix.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@ import CNIOLinux
1818

1919
private let sys_pthread_getname_np = CNIOLinux_pthread_getname_np
2020
private let sys_pthread_setname_np = CNIOLinux_pthread_setname_np
21+
#if os(Android)
22+
private typealias ThreadDestructor = @convention(c) (UnsafeMutableRawPointer) ->
23+
UnsafeMutableRawPointer
24+
#else
2125
private typealias ThreadDestructor = @convention(c) (UnsafeMutableRawPointer?) ->
2226
UnsafeMutableRawPointer?
27+
#endif
2328
#elseif canImport(Darwin)
2429
import Darwin
2530

@@ -119,7 +124,11 @@ enum ThreadOpsPosix: ThreadOps {
119124

120125
body(Thread(handle: hThread, desiredName: name))
121126

127+
#if os(Android)
128+
return UnsafeMutableRawPointer(bitPattern: 0xdeadbee)!
129+
#else
122130
return nil
131+
#endif
123132
},
124133
args: argv0
125134
)

Sources/NIOFileSystem/Internal/System Calls/Syscall.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ public enum Syscall {
239239
size: Int
240240
) -> Result<Int, Errno> {
241241
valueOrErrno(retryOnInterrupt: false) {
242-
system_sendfile(output.rawValue, input.rawValue, offset, size)
242+
system_sendfile(output.rawValue, input.rawValue, off_t(offset), size)
243243
}
244244
}
245245
#endif
@@ -347,7 +347,11 @@ public enum Libc {
347347
return valueOrErrno {
348348
pathBytes.withUnsafeMutableBufferPointer { pointer in
349349
// The array must be terminated with a nil.
350+
#if os(Android)
351+
libc_fts_open([pointer.baseAddress!, unsafeBitCast(0, to: UnsafeMutablePointer<CInterop.PlatformChar>.self)], options.rawValue)
352+
#else
350353
libc_fts_open([pointer.baseAddress, nil], options.rawValue)
354+
#endif
351355
}
352356
}
353357
}

Sources/NIOFileSystem/Internal/System Calls/Syscalls.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ internal func system_sendfile(
330330
internal func libc_fdopendir(
331331
_ fd: FileDescriptor.RawValue
332332
) -> CInterop.DirPointer {
333-
return fdopendir(fd)
333+
return fdopendir(fd)!
334334
}
335335

336336
/// readdir(3): Returns a pointer to the next directory entry
@@ -396,12 +396,21 @@ internal func libc_confstr(
396396
#endif
397397

398398
/// fts(3)
399+
#if os(Android)
400+
internal func libc_fts_open(
401+
_ path: [UnsafeMutablePointer<CInterop.PlatformChar>],
402+
_ options: CInt
403+
) -> UnsafeMutablePointer<CInterop.FTS> {
404+
return fts_open(path, options, nil)!
405+
}
406+
#else
399407
internal func libc_fts_open(
400408
_ path: [UnsafeMutablePointer<CInterop.PlatformChar>?],
401409
_ options: CInt
402410
) -> UnsafeMutablePointer<CInterop.FTS> {
403411
return fts_open(path, options, nil)
404412
}
413+
#endif
405414

406415
/// fts(3)
407416
internal func libc_fts_read(

Sources/NIOFileSystem/Internal/SystemFileHandle.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,17 +1116,28 @@ extension SystemFileHandle {
11161116
if delayMaterialization {
11171117
// When opening in this mode we can more "atomically" create the file, that is, by not
11181118
// leaving the user with a half written file should e.g. the system crash or throw an
1119-
// error while writing. On Linux we do this by opening the directory for the path
1120-
// with `O_TMPFILE` and creating a hard link when closing the file. On other platforms
1121-
// we generate a dot file with a randomised suffix name and rename it to the
1119+
// error while writing. On non-Android Linux we do this by opening the directory for
1120+
// the path with `O_TMPFILE` and creating a hard link when closing the file. On other
1121+
// platforms we generate a dot file with a randomised suffix name and rename it to the
11221122
// destination.
1123+
#if os(Android)
1124+
return Self.syncOpenWithMaterialization(
1125+
atPath: path,
1126+
mode: mode,
1127+
options: options,
1128+
permissions: permissions,
1129+
executor: executor,
1130+
useTemporaryFileIfPossible: false
1131+
)
1132+
#else
11231133
return Self.syncOpenWithMaterialization(
11241134
atPath: path,
11251135
mode: mode,
11261136
options: options,
11271137
permissions: permissions,
11281138
executor: executor
11291139
)
1140+
#endif
11301141
} else {
11311142
return Self.syncOpen(
11321143
atPath: path,

Tests/NIOFileSystemIntegrationTests/FileHandleTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ final class FileHandleTests: XCTestCase {
3434
autoClose: Bool = true,
3535
_ execute: @Sendable (SystemFileHandle) async throws -> Void
3636
) async throws {
37-
let path = FilePath("/tmp/\(Self.temporaryFileName())")
37+
let path = FilePath("\(FileManager.default.temporaryDirectory.path)/\(Self.temporaryFileName())")
3838
defer {
3939
// Remove the file when we're done.
4040
XCTAssertNoThrow(try Libc.remove(path).get())

Tests/NIOFileSystemTests/FileInfoTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ final class FileInfoTests: XCTestCase {
2626
private var status: CInterop.Stat {
2727
var status = CInterop.Stat()
2828
status.st_dev = 1
29-
status.st_mode = S_IFREG | 0o777
29+
status.st_mode = .init(S_IFREG | 0o777)
3030
status.st_nlink = 3
3131
status.st_ino = 4
3232
status.st_uid = 5

0 commit comments

Comments
 (0)