From b3c8ce0711de037b6362ae57e9b9e484fbc5e8c4 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Thu, 29 Feb 2024 10:20:27 -0800 Subject: [PATCH] Foundation: repair the build for Android API level 28+ The newer level introduces APIs with additional nullability attribution. This causes issues as the attribution sometimes collides with expectations. Unwrap more cases to appease the nullability attributes. One problematic area of this change is the handling for `Process.run()`. The posix spawn APIs are described as: ``` typedef struct __posix_spawnattr* posix_spawnattr_t; int posix_spawnattr_init(posix_spawnattr_t _Nonnull * _Nonnull __attr); ``` As the inner `_Nonnull` appertains to `posix_spawnattr_t`, it expects a non-null pointer to a non-null pointer. However, as `struct __posix_spawnattr` is opaque, we cannot allocate space for it and thus must be acceptable to take a pointer to null to permit the allocation. --- Sources/Foundation/FileHandle.swift | 2 +- Sources/Foundation/FileManager+POSIX.swift | 24 +++++++++++++--------- Sources/Foundation/FileManager.swift | 8 ++++---- Sources/Foundation/Host.swift | 2 +- Sources/Foundation/Process.swift | 7 +++++++ 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/Sources/Foundation/FileHandle.swift b/Sources/Foundation/FileHandle.swift index a538a2975ee..8a305b88401 100644 --- a/Sources/Foundation/FileHandle.swift +++ b/Sources/Foundation/FileHandle.swift @@ -310,7 +310,7 @@ open class FileHandle : NSObject { let data = mmap(nil, mapSize, PROT_READ, MAP_PRIVATE, _fd, 0) // Swift does not currently expose MAP_FAILURE if data != UnsafeMutableRawPointer(bitPattern: -1) { - return NSData.NSDataReadResult(bytes: data!, length: mapSize) { buffer, length in + return NSData.NSDataReadResult(bytes: data, length: mapSize) { buffer, length in munmap(buffer, length) } } diff --git a/Sources/Foundation/FileManager+POSIX.swift b/Sources/Foundation/FileManager+POSIX.swift index d90ece91e69..613892eb848 100644 --- a/Sources/Foundation/FileManager+POSIX.swift +++ b/Sources/Foundation/FileManager+POSIX.swift @@ -744,17 +744,19 @@ extension FileManager { let ps = UnsafeMutablePointer?>.allocate(capacity: 2) ps.initialize(to: UnsafeMutablePointer(mutating: fsRep)) ps.advanced(by: 1).initialize(to: nil) - let stream = fts_open(ps, FTS_PHYSICAL | FTS_XDEV | FTS_NOCHDIR | FTS_NOSTAT, nil) + let stream = ps.withMemoryRebound(to: UnsafeMutablePointer.self, capacity: 2) { + fts_open($0, FTS_PHYSICAL | FTS_XDEV | FTS_NOCHDIR | FTS_NOSTAT, nil) + } ps.deinitialize(count: 2) ps.deallocate() - if stream != nil { + if let stream { defer { fts_close(stream) } - while let current = fts_read(stream)?.pointee { - let itemPath = string(withFileSystemRepresentation: current.fts_path, length: Int(current.fts_pathlen)) + while let current = fts_read(stream)?.pointee, let fts_path = current.fts_path { + let itemPath = string(withFileSystemRepresentation: fts_path, length: Int(current.fts_pathlen)) guard alreadyConfirmed || shouldRemoveItemAtPath(itemPath, isURL: isURL) else { continue } @@ -762,11 +764,11 @@ extension FileManager { do { switch Int32(current.fts_info) { case FTS_DEFAULT, FTS_F, FTS_NSOK, FTS_SL, FTS_SLNONE: - if unlink(current.fts_path) == -1 { + if unlink(fts_path) == -1 { throw _NSErrorWithErrno(errno, reading: false, path: itemPath) } case FTS_DP: - if rmdir(current.fts_path) == -1 { + if rmdir(fts_path) == -1 { throw _NSErrorWithErrno(errno, reading: false, path: itemPath) } case FTS_DNR, FTS_ERR, FTS_NS: @@ -1089,7 +1091,9 @@ extension FileManager { defer { ps.deallocate() } ps.initialize(to: UnsafeMutablePointer(mutating: fsRep)) ps.advanced(by: 1).initialize(to: nil) - return fts_open(ps, FTS_PHYSICAL | FTS_XDEV | FTS_NOCHDIR | FTS_NOSTAT, nil) + return ps.withMemoryRebound(to: UnsafeMutablePointer.self, capacity: 2) { + fts_open($0, FTS_PHYSICAL | FTS_XDEV | FTS_NOCHDIR | FTS_NOSTAT, nil) + } } if _stream == nil { throw _NSErrorWithErrno(errno, reading: true, url: url) @@ -1136,13 +1140,13 @@ extension FileManager { _current = fts_read(stream) while let current = _current { - let filename = FileManager.default.string(withFileSystemRepresentation: current.pointee.fts_path, length: Int(current.pointee.fts_pathlen)) + let filename = FileManager.default.string(withFileSystemRepresentation: current.pointee.fts_path!, length: Int(current.pointee.fts_pathlen)) switch Int32(current.pointee.fts_info) { case FTS_D: let (showFile, skipDescendants) = match(filename: filename, to: _options, isDir: true) if skipDescendants { - fts_set(_stream, _current, FTS_SKIP) + fts_set(stream, _current!, FTS_SKIP) } if showFile { return URL(fileURLWithPath: filename, isDirectory: true) @@ -1315,7 +1319,7 @@ extension FileManager { let finalErrno = originalItemURL.withUnsafeFileSystemRepresentation { (originalFS) -> Int32? in return newItemURL.withUnsafeFileSystemRepresentation { (newItemFS) -> Int32? in // This is an atomic operation in many OSes, but is not guaranteed to be atomic by the standard. - if rename(newItemFS, originalFS) == 0 { + if rename(newItemFS!, originalFS!) == 0 { return nil } else { return errno diff --git a/Sources/Foundation/FileManager.swift b/Sources/Foundation/FileManager.swift index 1aa3038a01f..db62c9b206d 100644 --- a/Sources/Foundation/FileManager.swift +++ b/Sources/Foundation/FileManager.swift @@ -568,13 +568,13 @@ open class FileManager : NSObject { let attributes = try windowsFileAttributes(atPath: path) let type = FileAttributeType(attributes: attributes, atPath: path) #else - if let pwd = getpwuid(s.st_uid), pwd.pointee.pw_name != nil { - let name = String(cString: pwd.pointee.pw_name) + if let pwd = getpwuid(s.st_uid), let pw_name = pwd.pointee.pw_name { + let name = String(cString: pw_name) result[.ownerAccountName] = name } - if let grd = getgrgid(s.st_gid), grd.pointee.gr_name != nil { - let name = String(cString: grd.pointee.gr_name) + if let grd = getgrgid(s.st_gid), let gr_name = grd.pointee.gr_name { + let name = String(cString: gr_name) result[.groupOwnerAccountName] = name } diff --git a/Sources/Foundation/Host.swift b/Sources/Foundation/Host.swift index 5fe7b29c5b9..0c94801803b 100644 --- a/Sources/Foundation/Host.swift +++ b/Sources/Foundation/Host.swift @@ -24,7 +24,7 @@ import WinSDK } // getnameinfo uses size_t for its 4th and 6th arguments. - private func getnameinfo(_ addr: UnsafePointer?, _ addrlen: socklen_t, _ host: UnsafeMutablePointer?, _ hostlen: socklen_t, _ serv: UnsafeMutablePointer?, _ servlen: socklen_t, _ flags: Int32) -> Int32 { + private func getnameinfo(_ addr: UnsafePointer, _ addrlen: socklen_t, _ host: UnsafeMutablePointer?, _ hostlen: socklen_t, _ serv: UnsafeMutablePointer?, _ servlen: socklen_t, _ flags: Int32) -> Int32 { return Glibc.getnameinfo(addr, addrlen, host, Int(hostlen), serv, Int(servlen), flags) } diff --git a/Sources/Foundation/Process.swift b/Sources/Foundation/Process.swift index 542cc94cf12..187097b3da6 100644 --- a/Sources/Foundation/Process.swift +++ b/Sources/Foundation/Process.swift @@ -927,6 +927,13 @@ open class Process: NSObject { var spawnAttrs: posix_spawnattr_t? = nil #else var spawnAttrs: posix_spawnattr_t = posix_spawnattr_t() +#endif +#if os(Android) + guard var spawnAttrs else { + throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: [ + NSURLErrorKey:self.executableURL! + ]) + } #endif try _throwIfPosixError(posix_spawnattr_init(&spawnAttrs)) try _throwIfPosixError(posix_spawnattr_setflags(&spawnAttrs, .init(POSIX_SPAWN_SETPGROUP)))