From e22cb7f8085fc0e653866236f2c6d0762a47ea1d Mon Sep 17 00:00:00 2001 From: Jeremy Schonfeld Date: Tue, 3 Dec 2024 14:17:22 -0800 Subject: [PATCH 1/9] [Windows] FileManager.enumerator(at:) default error handler should continue rather than exiting (#5136) (#5138) --- Sources/Foundation/FileManager+Win32.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/Foundation/FileManager+Win32.swift b/Sources/Foundation/FileManager+Win32.swift index 3f8c7f9cac..b761c3550a 100644 --- a/Sources/Foundation/FileManager+Win32.swift +++ b/Sources/Foundation/FileManager+Win32.swift @@ -322,11 +322,11 @@ extension FileManager { override func nextObject() -> Any? { func firstValidItem() -> URL? { while let url = _stack.popLast() { - if !FileManager.default.fileExists(atPath: url.path) { - guard let handler = _errorHandler else { return nil } - if !handler(url, _NSErrorWithWindowsError(GetLastError(), reading: true, paths: [url.path])) { + guard FileManager.default.fileExists(atPath: url.path) else { + if let handler = _errorHandler, !handler(url, _NSErrorWithWindowsError(GetLastError(), reading: true, paths: [url.path])) { return nil } + continue } _lastReturned = url return _lastReturned From f9fae48282c9c541da3db892b0cc15c6e65a36d8 Mon Sep 17 00:00:00 2001 From: Jeremy Schonfeld Date: Thu, 12 Dec 2024 09:36:17 -0800 Subject: [PATCH 2/9] Home directory for non-existent user should not fall back to /var/empty or %ALLUSERSPROFILE% (#5142) (#5145) --- Tests/Foundation/TestFileManager.swift | 10 ++++------ Tests/Foundation/TestNSString.swift | 6 +----- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/Tests/Foundation/TestFileManager.swift b/Tests/Foundation/TestFileManager.swift index 1ed44a8b18..faff3631d4 100644 --- a/Tests/Foundation/TestFileManager.swift +++ b/Tests/Foundation/TestFileManager.swift @@ -929,8 +929,8 @@ class TestFileManager : XCTestCase { func test_homedirectoryForUser() { let filemanger = FileManager.default - XCTAssertNotNil(filemanger.homeDirectory(forUser: "someuser")) - XCTAssertNotNil(filemanger.homeDirectory(forUser: "")) + XCTAssertNil(filemanger.homeDirectory(forUser: "someuser")) + XCTAssertNil(filemanger.homeDirectory(forUser: "")) XCTAssertNotNil(filemanger.homeDirectoryForCurrentUser) } @@ -1268,15 +1268,13 @@ class TestFileManager : XCTestCase { let fm = FileManager.default #if os(Windows) - let defaultHomeDirectory = ProcessInfo.processInfo.environment["ALLUSERSPROFILE"]! let emptyFileNameError: CocoaError.Code? = .fileReadInvalidFileName #else - let defaultHomeDirectory = "/var/empty" let emptyFileNameError: CocoaError.Code? = nil #endif - XCTAssertEqual(fm.homeDirectory(forUser: ""), URL(filePath: defaultHomeDirectory, directoryHint: .isDirectory)) - XCTAssertEqual(NSHomeDirectoryForUser(""), defaultHomeDirectory) + XCTAssertNil(fm.homeDirectory(forUser: "")) + XCTAssertNil(NSHomeDirectoryForUser("")) XCTAssertThrowsError(try fm.contentsOfDirectory(atPath: "")) { let code = ($0 as? CocoaError)?.code diff --git a/Tests/Foundation/TestNSString.swift b/Tests/Foundation/TestNSString.swift index 130dbbd8c0..b3e24278a3 100644 --- a/Tests/Foundation/TestNSString.swift +++ b/Tests/Foundation/TestNSString.swift @@ -1047,11 +1047,7 @@ class TestNSString: LoopbackServerTest { let path = NSString(string: "~\(userName)/") let result = path.expandingTildeInPath // next assert fails in VirtualBox because home directory for unknown user resolved to /var/run/vboxadd - #if os(Windows) - XCTAssertEqual(result, ProcessInfo.processInfo.environment["ALLUSERSPROFILE"]) - #else - XCTAssertEqual(result, "/var/empty", "Return copy of receiver if home directory could not be resolved.") - #endif + XCTAssertEqual(result, "~\(userName)", "Return copy of receiver if home directory could not be resolved.") } } From 739c14ed1850b1908bfca988c8f90b62ab8be00d Mon Sep 17 00:00:00 2001 From: finagolfin Date: Thu, 19 Dec 2024 23:48:47 +0530 Subject: [PATCH 3/9] [6.1][Android] Get this repo building again (#5151) * [android] Fix package manifest and one Bionic function's API version * Merge commit '246b3474fd4cb91d13b5ecb8fb5175aa6b50aa1e' into github/main * Fix fts_open now that apinotes are applied * Update Sources/Foundation/FileManager+POSIX.swift * fix Port.swift conditional * Ensure that the Android build on a windows host doesn't turn on WMO yet The windows host builds with the old driver for now, so it doesn't yet support wmo * [android] fix pthread flag inclusion in libxml2 package * review fixes * [android] Use Bionic imports instead where possible --------- Co-authored-by: Alex Lorenz Co-authored-by: Saleem Abdulrasool --- CMakeLists.txt | 8 +++++++- Package.swift | 11 ++++++----- Sources/CoreFoundation/CFPlatform.c | 2 +- .../CoreFoundation/include/ForSwiftFoundationOnly.h | 7 +++++++ .../internalInclude/CoreFoundation_Prefix.h | 6 +++--- Sources/Foundation/CGFloat.swift | 4 ++++ Sources/Foundation/FileHandle.swift | 7 ++++++- Sources/Foundation/FileManager+POSIX.swift | 10 +++++++--- Sources/Foundation/FileManager.swift | 2 ++ Sources/Foundation/Host.swift | 9 +++++---- Sources/Foundation/NSData.swift | 5 +++++ Sources/Foundation/NSError.swift | 2 ++ Sources/Foundation/NSLock.swift | 2 ++ Sources/Foundation/NSPathUtilities.swift | 2 ++ Sources/Foundation/NSPlatform.swift | 3 +++ Sources/Foundation/NSSwiftRuntime.swift | 2 ++ Sources/Foundation/NSURL.swift | 2 ++ Sources/Foundation/Port.swift | 11 ++++++++--- Sources/Foundation/Process.swift | 9 +++++++++ Sources/Foundation/Thread.swift | 2 ++ Sources/FoundationNetworking/HTTPCookie.swift | 2 ++ Sources/Testing/Testing.swift | 2 ++ Sources/plutil/main.swift | 3 +++ Sources/xdgTestHelper/main.swift | 2 ++ Tests/Foundation/FTPServer.swift | 2 ++ Tests/Foundation/HTTPServer.swift | 2 ++ Tests/Foundation/TestFileHandle.swift | 4 +++- Tests/Foundation/TestNSData.swift | 8 ++++++++ Tests/Foundation/TestProcess.swift | 3 +++ Tests/Foundation/TestSocketPort.swift | 2 ++ Tests/Foundation/TestTimeZone.swift | 2 +- Tests/Foundation/TestURL.swift | 4 ++++ 32 files changed, 119 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 62a9c6a225..265c9d3de7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ if(NOT SWIFT_SYSTEM_NAME) endif() # Don't enable WMO on Windows due to linker failures -if(NOT CMAKE_SYSTEM_NAME STREQUAL Windows) +if(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) # Enable whole module optimization for release builds & incremental for debug builds if(POLICY CMP0157) set(CMAKE_Swift_COMPILATION_MODE "$,wholemodule,incremental>") @@ -150,6 +150,12 @@ if(NOT CMAKE_SYSTEM_NAME STREQUAL "WASI") "-I${DISPATCH_INCLUDE_PATH}/Block") endif() endif() +if(ANDROID) + # LibXml2 looks for the Threads package, so + # ensure that it doesn't try to use the `-pthread` + # flag on Android. + set(CMAKE_HAVE_LIBC_PTHREAD YES) +endif() find_package(LibXml2 REQUIRED) if(FOUNDATION_BUILD_NETWORKING) find_package(CURL REQUIRED) diff --git a/Package.swift b/Package.swift index 2b5b5e0534..4a9dc5dc71 100644 --- a/Package.swift +++ b/Package.swift @@ -26,7 +26,7 @@ if let environmentPath = Context.environment["DISPATCH_INCLUDE_PATH"] { .unsafeFlags([ "-I/usr/lib/swift", "-I/usr/lib/swift/Block" - ], .when(platforms: [.linux, .android])) + ], .when(platforms: [.linux])) ) if let sdkRoot = Context.environment["SDKROOT"] { dispatchIncludeFlags.append(.unsafeFlags([ @@ -245,7 +245,8 @@ let package = Package( "BlockRuntime", "CMakeLists.txt" ], - cSettings: coreFoundationBuildSettings + cSettings: coreFoundationBuildSettings, + linkerSettings: [.linkedLibrary("log", .when(platforms: [.android]))] ), .target( name: "BlocksRuntime", @@ -262,7 +263,7 @@ let package = Package( name: "_CFXMLInterface", dependencies: [ "CoreFoundation", - .target(name: "Clibxml2", condition: .when(platforms: [.linux])), + .target(name: "Clibxml2", condition: .when(platforms: [.linux, .android])), ], path: "Sources/_CFXMLInterface", exclude: [ @@ -275,7 +276,7 @@ let package = Package( name: "_CFURLSessionInterface", dependencies: [ "CoreFoundation", - .target(name: "Clibcurl", condition: .when(platforms: [.linux])), + .target(name: "Clibcurl", condition: .when(platforms: [.linux, .android])), ], path: "Sources/_CFURLSessionInterface", exclude: [ @@ -348,7 +349,7 @@ let package = Package( "FoundationNetworking", "XCTest", "Testing", - .target(name: "xdgTestHelper", condition: .when(platforms: [.linux])) + .target(name: "xdgTestHelper", condition: .when(platforms: [.linux, .android])) ], resources: [ .copy("Foundation/Resources") diff --git a/Sources/CoreFoundation/CFPlatform.c b/Sources/CoreFoundation/CFPlatform.c index 83fbfd7743..90f4aa78df 100644 --- a/Sources/CoreFoundation/CFPlatform.c +++ b/Sources/CoreFoundation/CFPlatform.c @@ -2283,7 +2283,7 @@ CF_EXPORT int _CFPosixSpawnFileActionsChdir(_CFPosixSpawnFileActionsRef file_act // Glibc versions prior to 2.29 don't support posix_spawn_file_actions_addchdir_np, impacting: // - Amazon Linux 2 (EoL mid-2025) return ENOSYS; - #elif defined(__GLIBC__) || TARGET_OS_DARWIN || defined(__FreeBSD__) || defined(__ANDROID__) || defined(__musl__) + #elif defined(__GLIBC__) || TARGET_OS_DARWIN || defined(__FreeBSD__) || (defined(__ANDROID__) && __ANDROID_API__ >= 34) || defined(__musl__) // Pre-standard posix_spawn_file_actions_addchdir_np version available in: // - Solaris 11.3 (October 2015) // - Glibc 2.29 (February 2019) diff --git a/Sources/CoreFoundation/include/ForSwiftFoundationOnly.h b/Sources/CoreFoundation/include/ForSwiftFoundationOnly.h index 88fb3d361f..53a5d56052 100644 --- a/Sources/CoreFoundation/include/ForSwiftFoundationOnly.h +++ b/Sources/CoreFoundation/include/ForSwiftFoundationOnly.h @@ -69,6 +69,13 @@ #include #include #include +#include +#ifdef __swift__ +// The linux/stat header is private in the Android modulemap. +#pragma clang module import posix_filesystem.linux_stat +#else +#include +#endif #elif TARGET_OS_WASI #include #include diff --git a/Sources/CoreFoundation/internalInclude/CoreFoundation_Prefix.h b/Sources/CoreFoundation/internalInclude/CoreFoundation_Prefix.h index 6dea303681..1cbefad215 100644 --- a/Sources/CoreFoundation/internalInclude/CoreFoundation_Prefix.h +++ b/Sources/CoreFoundation/internalInclude/CoreFoundation_Prefix.h @@ -200,9 +200,9 @@ static dispatch_queue_t __ ## PREFIX ## Queue(void) { \ #endif // We know some things (Darwin, WASI, Glibc >= 2.38) have strlcpy/strlcat -#if TARGET_OS_MAC || TARGET_OS_WASI \ - || (defined(__GLIBC__) && \ - ((__GLIBC_MAJOR__ == 2 && __GLIBC_MINOR__ >= 38) \ +#if TARGET_OS_MAC || TARGET_OS_WASI || TARGET_OS_ANDROID \ + || (defined(__GLIBC__) && \ + ((__GLIBC_MAJOR__ == 2 && __GLIBC_MINOR__ >= 38) \ || __GLIBC_MAJOR__ > 2)) #define HAVE_STRLCPY 1 #define HAVE_STRLCAT 1 diff --git a/Sources/Foundation/CGFloat.swift b/Sources/Foundation/CGFloat.swift index ffe3a6c6ff..c59977f88a 100644 --- a/Sources/Foundation/CGFloat.swift +++ b/Sources/Foundation/CGFloat.swift @@ -7,6 +7,10 @@ // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // +#if canImport(Android) +import Android +#endif + @frozen public struct CGFloat: Sendable { #if arch(i386) || arch(arm) || arch(wasm32) diff --git a/Sources/Foundation/FileHandle.swift b/Sources/Foundation/FileHandle.swift index b07c49acca..7a985f2ef8 100644 --- a/Sources/Foundation/FileHandle.swift +++ b/Sources/Foundation/FileHandle.swift @@ -34,6 +34,11 @@ import WASILibc fileprivate let _read = WASILibc.read(_:_:_:) fileprivate let _write = WASILibc.write(_:_:_:) fileprivate let _close = WASILibc.close(_:) +#elseif canImport(Android) +import Android +fileprivate let _read = Android.read(_:_:_:) +fileprivate let _write = Android.write(_:_:_:) +fileprivate let _close = Android.close(_:) #endif #if canImport(WinSDK) @@ -324,7 +329,7 @@ open class FileHandle : NSObject, @unchecked Sendable { 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 845ca89221..89bc95b101 100644 --- a/Sources/Foundation/FileManager+POSIX.swift +++ b/Sources/Foundation/FileManager+POSIX.swift @@ -7,6 +7,10 @@ // #if !os(Windows) +#if canImport(Android) +import Android +#endif + #if os(Android) && (arch(i386) || arch(arm)) // struct stat.st_mode is UInt32 internal func &(left: UInt32, right: mode_t) -> mode_t { return mode_t(left) & right @@ -398,13 +402,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) @@ -578,7 +582,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 5a68934853..c28ee293b7 100644 --- a/Sources/Foundation/FileManager.swift +++ b/Sources/Foundation/FileManager.swift @@ -21,6 +21,8 @@ import WinSDK #if os(WASI) import WASILibc +#elseif canImport(Bionic) +import Bionic #endif #if os(Windows) diff --git a/Sources/Foundation/Host.swift b/Sources/Foundation/Host.swift index 6c4f5291f6..fb13063121 100644 --- a/Sources/Foundation/Host.swift +++ b/Sources/Foundation/Host.swift @@ -12,8 +12,9 @@ import WinSDK #endif -#if os(Android) - // Android Glibc differs a little with respect to the Linux Glibc. +#if canImport(Android) + import Android + // Android Bionic differs a little with respect to the Linux Glibc. // IFF_LOOPBACK is part of the enumeration net_device_flags, which needs to // convert to UInt32. @@ -24,8 +25,8 @@ 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 { - return Glibc.getnameinfo(addr, addrlen, host, Int(hostlen), serv, Int(servlen), flags) + private func getnameinfo(_ addr: UnsafePointer, _ addrlen: socklen_t, _ host: UnsafeMutablePointer?, _ hostlen: socklen_t, _ serv: UnsafeMutablePointer?, _ servlen: socklen_t, _ flags: Int32) -> Int32 { + return Android.getnameinfo(addr, addrlen, host, Int(hostlen), serv, Int(servlen), flags) } // getifaddrs and freeifaddrs are not available in Android 6.0 or earlier, so call these functions dynamically. diff --git a/Sources/Foundation/NSData.swift b/Sources/Foundation/NSData.swift index ae54f971ec..65eb0d93e2 100644 --- a/Sources/Foundation/NSData.swift +++ b/Sources/Foundation/NSData.swift @@ -11,6 +11,9 @@ #if !os(WASI) import Dispatch #endif +#if canImport(Android) +import Android +#endif extension NSData { public typealias ReadingOptions = Data.ReadingOptions @@ -469,6 +472,8 @@ open class NSData : NSObject, NSCopying, NSMutableCopying, NSSecureCoding { let createMode = Int(Musl.S_IRUSR) | Int(Musl.S_IWUSR) | Int(Musl.S_IRGRP) | Int(Musl.S_IWGRP) | Int(Musl.S_IROTH) | Int(Musl.S_IWOTH) #elseif canImport(WASILibc) let createMode = Int(WASILibc.S_IRUSR) | Int(WASILibc.S_IWUSR) | Int(WASILibc.S_IRGRP) | Int(WASILibc.S_IWGRP) | Int(WASILibc.S_IROTH) | Int(WASILibc.S_IWOTH) +#elseif canImport(Android) + let createMode = Int(Android.S_IRUSR) | Int(Android.S_IWUSR) | Int(Android.S_IRGRP) | Int(Android.S_IWGRP) | Int(Android.S_IROTH) | Int(Android.S_IWOTH) #endif guard let fh = FileHandle(path: path, flags: flags, createMode: createMode) else { throw _NSErrorWithErrno(errno, reading: false, path: path) diff --git a/Sources/Foundation/NSError.swift b/Sources/Foundation/NSError.swift index 2b75bd4ffd..9543fb0c56 100644 --- a/Sources/Foundation/NSError.swift +++ b/Sources/Foundation/NSError.swift @@ -16,6 +16,8 @@ import Darwin import Glibc #elseif canImport(CRT) import CRT +#elseif canImport(Android) +import Android #endif @_implementationOnly import CoreFoundation diff --git a/Sources/Foundation/NSLock.swift b/Sources/Foundation/NSLock.swift index fe1d08b775..9d0fadc910 100644 --- a/Sources/Foundation/NSLock.swift +++ b/Sources/Foundation/NSLock.swift @@ -11,6 +11,8 @@ #if canImport(Glibc) import Glibc +#elseif canImport(Bionic) +import Bionic #endif #if os(Windows) diff --git a/Sources/Foundation/NSPathUtilities.swift b/Sources/Foundation/NSPathUtilities.swift index e9c300096c..ba8a48fad3 100644 --- a/Sources/Foundation/NSPathUtilities.swift +++ b/Sources/Foundation/NSPathUtilities.swift @@ -10,6 +10,8 @@ @_implementationOnly import CoreFoundation #if os(Windows) import WinSDK +#elseif canImport(Android) +import Android #elseif os(WASI) import WASILibc #endif diff --git a/Sources/Foundation/NSPlatform.swift b/Sources/Foundation/NSPlatform.swift index a18090265d..5424f5bb92 100644 --- a/Sources/Foundation/NSPlatform.swift +++ b/Sources/Foundation/NSPlatform.swift @@ -10,6 +10,9 @@ #if os(macOS) || os(iOS) fileprivate let _NSPageSize = Int(vm_page_size) #elseif os(Linux) || os(Android) || os(OpenBSD) +#if canImport(Android) +import Android +#endif fileprivate let _NSPageSize = Int(getpagesize()) #elseif os(Windows) import WinSDK diff --git a/Sources/Foundation/NSSwiftRuntime.swift b/Sources/Foundation/NSSwiftRuntime.swift index 03176c17cf..1509c31d71 100644 --- a/Sources/Foundation/NSSwiftRuntime.swift +++ b/Sources/Foundation/NSSwiftRuntime.swift @@ -19,6 +19,8 @@ internal import Synchronization @_exported import Glibc #elseif canImport(Musl) @_exported import Musl +#elseif canImport(Bionic) +@_exported import Bionic #elseif os(WASI) @_exported import WASILibc #elseif os(Windows) diff --git a/Sources/Foundation/NSURL.swift b/Sources/Foundation/NSURL.swift index fc22292b7e..a9972c1ac2 100644 --- a/Sources/Foundation/NSURL.swift +++ b/Sources/Foundation/NSURL.swift @@ -22,6 +22,8 @@ import Darwin import Glibc #elseif canImport(Musl) import Musl +#elseif canImport(Bionic) +import Bionic #endif // NOTE: this represents PLATFORM_PATH_STYLE diff --git a/Sources/Foundation/Port.swift b/Sources/Foundation/Port.swift index acef3c9960..2185836818 100644 --- a/Sources/Foundation/Port.swift +++ b/Sources/Foundation/Port.swift @@ -107,7 +107,7 @@ fileprivate let FOUNDATION_SOCK_STREAM = SOCK_STREAM fileprivate let FOUNDATION_IPPROTO_TCP = IPPROTO_TCP #endif -#if canImport(Glibc) && !os(Android) && !os(OpenBSD) +#if canImport(Glibc) && !os(OpenBSD) import Glibc fileprivate let FOUNDATION_SOCK_STREAM = Int32(SOCK_STREAM.rawValue) fileprivate let FOUNDATION_IPPROTO_TCP = Int32(IPPROTO_TCP) @@ -119,14 +119,19 @@ fileprivate let FOUNDATION_SOCK_STREAM = Int32(SOCK_STREAM) fileprivate let FOUNDATION_IPPROTO_TCP = Int32(IPPROTO_TCP) #endif -#if canImport(Glibc) && os(Android) || os(OpenBSD) +#if canImport(Glibc) && os(OpenBSD) import Glibc fileprivate let FOUNDATION_SOCK_STREAM = Int32(SOCK_STREAM) fileprivate let FOUNDATION_IPPROTO_TCP = Int32(IPPROTO_TCP) fileprivate let INADDR_ANY: in_addr_t = 0 -#if os(OpenBSD) fileprivate let INADDR_LOOPBACK = 0x7f000001 #endif + +#if canImport(Android) +import Android +fileprivate let FOUNDATION_SOCK_STREAM = Int32(Android.SOCK_STREAM) +fileprivate let FOUNDATION_IPPROTO_TCP = Int32(Android.IPPROTO_TCP) +fileprivate let INADDR_ANY: in_addr_t = 0 #endif diff --git a/Sources/Foundation/Process.swift b/Sources/Foundation/Process.swift index 758dd1dfd4..7d6a1a3952 100644 --- a/Sources/Foundation/Process.swift +++ b/Sources/Foundation/Process.swift @@ -18,6 +18,8 @@ import struct WinSDK.HANDLE #if canImport(Darwin) import Darwin +#elseif canImport(Android) +import Android #endif internal import Synchronization @@ -940,6 +942,13 @@ open class Process: NSObject, @unchecked Sendable { 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))) diff --git a/Sources/Foundation/Thread.swift b/Sources/Foundation/Thread.swift index 5e79579c62..0985a4826d 100644 --- a/Sources/Foundation/Thread.swift +++ b/Sources/Foundation/Thread.swift @@ -17,6 +17,8 @@ import WinSDK import Glibc #elseif canImport(Musl) import Musl +#elseif canImport(Bionic) +import Bionic #endif // WORKAROUND_SR9811 diff --git a/Sources/FoundationNetworking/HTTPCookie.swift b/Sources/FoundationNetworking/HTTPCookie.swift index e0d1cbbd9f..237c1daf55 100644 --- a/Sources/FoundationNetworking/HTTPCookie.swift +++ b/Sources/FoundationNetworking/HTTPCookie.swift @@ -15,6 +15,8 @@ import Foundation #if os(Windows) import WinSDK +#elseif canImport(Android) +import Android #endif public struct HTTPCookiePropertyKey : RawRepresentable, Equatable, Hashable, Sendable { diff --git a/Sources/Testing/Testing.swift b/Sources/Testing/Testing.swift index 712d9deef4..2483c14ed6 100644 --- a/Sources/Testing/Testing.swift +++ b/Sources/Testing/Testing.swift @@ -11,6 +11,8 @@ import Glibc #elseif canImport(Musl) import Musl +#elseif canImport(Bionic) +import Bionic #elseif os(WASI) import WASILibc #elseif canImport(CRT) diff --git a/Sources/plutil/main.swift b/Sources/plutil/main.swift index 29316d165b..29584596d3 100644 --- a/Sources/plutil/main.swift +++ b/Sources/plutil/main.swift @@ -15,6 +15,9 @@ import Glibc #elseif canImport(Musl) import Foundation import Musl +#elseif canImport(Bionic) +import Foundation +import Bionic #elseif canImport(CRT) import Foundation import CRT diff --git a/Sources/xdgTestHelper/main.swift b/Sources/xdgTestHelper/main.swift index d515a63f04..fb037e2435 100644 --- a/Sources/xdgTestHelper/main.swift +++ b/Sources/xdgTestHelper/main.swift @@ -19,6 +19,8 @@ import FoundationNetworking #endif #if os(Windows) import WinSDK +#elseif canImport(Android) +import Android #endif enum HelperCheckStatus : Int32 { diff --git a/Tests/Foundation/FTPServer.swift b/Tests/Foundation/FTPServer.swift index bc3753baae..8328a7ff7e 100644 --- a/Tests/Foundation/FTPServer.swift +++ b/Tests/Foundation/FTPServer.swift @@ -15,6 +15,8 @@ import Dispatch import Glibc #elseif canImport(Darwin) import Darwin +#elseif canImport(Android) + import Android #endif final class ServerSemaphore : Sendable { diff --git a/Tests/Foundation/HTTPServer.swift b/Tests/Foundation/HTTPServer.swift index b1a18a61de..f5459ff4b3 100644 --- a/Tests/Foundation/HTTPServer.swift +++ b/Tests/Foundation/HTTPServer.swift @@ -21,6 +21,8 @@ import Dispatch import Darwin #elseif canImport(Glibc) import Glibc +#elseif canImport(Android) + import Android #endif #if !os(Windows) diff --git a/Tests/Foundation/TestFileHandle.swift b/Tests/Foundation/TestFileHandle.swift index f754361483..8650c207e2 100644 --- a/Tests/Foundation/TestFileHandle.swift +++ b/Tests/Foundation/TestFileHandle.swift @@ -19,6 +19,8 @@ import Dispatch #if os(Windows) import WinSDK +#elseif canImport(Android) +import Android #endif class TestFileHandle : XCTestCase { @@ -111,7 +113,7 @@ class TestFileHandle : XCTestCase { #else var fds: [Int32] = [-1, -1] fds.withUnsafeMutableBufferPointer { (pointer) -> Void in - pipe(pointer.baseAddress) + pipe(pointer.baseAddress!) } close(fds[1]) diff --git a/Tests/Foundation/TestNSData.swift b/Tests/Foundation/TestNSData.swift index 4ecb4eda2f..fc829994c7 100644 --- a/Tests/Foundation/TestNSData.swift +++ b/Tests/Foundation/TestNSData.swift @@ -10,6 +10,10 @@ import XCTest @testable import Foundation +#if canImport(Android) +import Android +#endif + class TestNSData: XCTestCase { class AllOnesImmutableData : NSData { @@ -213,6 +217,8 @@ class TestNSData: XCTestCase { let permission = try fileManager.attributesOfItem(atPath: url.path)[.posixPermissions] as? Int #if canImport(Darwin) let expected = Int(S_IRUSR) | Int(S_IWUSR) | Int(S_IRGRP) | Int(S_IWGRP) | Int(S_IROTH) | Int(S_IWOTH) +#elseif canImport(Android) + let expected = Int(Android.S_IRUSR) | Int(Android.S_IWUSR) | Int(Android.S_IRGRP) | Int(Android.S_IWGRP) | Int(Android.S_IROTH) | Int(Android.S_IWOTH) #else let expected = Int(Glibc.S_IRUSR) | Int(Glibc.S_IWUSR) | Int(Glibc.S_IRGRP) | Int(Glibc.S_IWGRP) | Int(Glibc.S_IROTH) | Int(Glibc.S_IWOTH) #endif @@ -236,6 +242,8 @@ class TestNSData: XCTestCase { let permission = try fileManager.attributesOfItem(atPath: url.path)[.posixPermissions] as? Int #if canImport(Darwin) let expected = Int(S_IRUSR) | Int(S_IWUSR) | Int(S_IRGRP) | Int(S_IWGRP) | Int(S_IROTH) | Int(S_IWOTH) +#elseif canImport(Android) + let expected = Int(Android.S_IRUSR) | Int(Android.S_IWUSR) | Int(Android.S_IRGRP) | Int(Android.S_IWGRP) | Int(Android.S_IROTH) | Int(Android.S_IWOTH) #else let expected = Int(Glibc.S_IRUSR) | Int(Glibc.S_IWUSR) | Int(Glibc.S_IRGRP) | Int(Glibc.S_IWGRP) | Int(Glibc.S_IROTH) | Int(Glibc.S_IWOTH) #endif diff --git a/Tests/Foundation/TestProcess.swift b/Tests/Foundation/TestProcess.swift index c0ec2268fe..219ae8b658 100644 --- a/Tests/Foundation/TestProcess.swift +++ b/Tests/Foundation/TestProcess.swift @@ -8,6 +8,9 @@ // import Synchronization +#if canImport(Android) +import Android +#endif class TestProcess : XCTestCase { diff --git a/Tests/Foundation/TestSocketPort.swift b/Tests/Foundation/TestSocketPort.swift index b79fb95073..0a6ec281a9 100644 --- a/Tests/Foundation/TestSocketPort.swift +++ b/Tests/Foundation/TestSocketPort.swift @@ -8,6 +8,8 @@ // #if os(Windows) import WinSDK +#elseif canImport(Android) +import Android #endif class TestPortDelegateWithBlock: NSObject, PortDelegate { diff --git a/Tests/Foundation/TestTimeZone.swift b/Tests/Foundation/TestTimeZone.swift index 6d2fbaf2ae..69b745df9f 100644 --- a/Tests/Foundation/TestTimeZone.swift +++ b/Tests/Foundation/TestTimeZone.swift @@ -164,7 +164,7 @@ class TestTimeZone: XCTestCase { var lt = tm() localtime_r(&t, <) let zoneName = NSTimeZone.system.abbreviation() ?? "Invalid Abbreviation" - let expectedName = String(cString: lt.tm_zone, encoding: .ascii) ?? "Invalid Zone" + let expectedName = String(cString: lt.tm_zone!, encoding: .ascii) ?? "Invalid Zone" XCTAssertEqual(zoneName, expectedName, "expected name \"\(expectedName)\" is not equal to \"\(zoneName)\"") } #endif diff --git a/Tests/Foundation/TestURL.swift b/Tests/Foundation/TestURL.swift index 4e044c05ec..cfd5eb258f 100644 --- a/Tests/Foundation/TestURL.swift +++ b/Tests/Foundation/TestURL.swift @@ -7,6 +7,10 @@ // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // +#if canImport(Android) +import Android +#endif + let kURLTestParsingTestsKey = "ParsingTests" let kURLTestTitleKey = "In-Title" From d6aed57c12543a14a3715e401dae8e770dbd8d30 Mon Sep 17 00:00:00 2001 From: Jeremy Schonfeld Date: Fri, 24 Jan 2025 09:46:37 -0800 Subject: [PATCH 4/9] Fix race condition in __CFStringGetEightBitStringEncoding (#5155) (#5156) --- Sources/CoreFoundation/include/ForFoundationOnly.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Sources/CoreFoundation/include/ForFoundationOnly.h b/Sources/CoreFoundation/include/ForFoundationOnly.h index 5bfea27735..b524163d4c 100644 --- a/Sources/CoreFoundation/include/ForFoundationOnly.h +++ b/Sources/CoreFoundation/include/ForFoundationOnly.h @@ -287,8 +287,11 @@ CF_EXPORT CFStringEncoding __CFDefaultEightBitStringEncoding; CF_EXPORT CFStringEncoding __CFStringComputeEightBitStringEncoding(void); CF_INLINE CFStringEncoding __CFStringGetEightBitStringEncoding(void) { - if (__CFDefaultEightBitStringEncoding == kCFStringEncodingInvalidId) __CFStringComputeEightBitStringEncoding(); - return __CFDefaultEightBitStringEncoding; + if (__CFDefaultEightBitStringEncoding == kCFStringEncodingInvalidId) { + return __CFStringComputeEightBitStringEncoding(); + } else { + return __CFDefaultEightBitStringEncoding; + } } enum { From 098065143d4b904ca07b3543290fb7f7d88a4538 Mon Sep 17 00:00:00 2001 From: Guoye Zhang Date: Mon, 10 Feb 2025 19:41:53 -0800 Subject: [PATCH 5/9] New HTTP loader for URLSession (#5168) --- Sources/Foundation/NSError.swift | 1 + Sources/Foundation/NSURLError.swift | 1 + Sources/FoundationNetworking/NSURLRequest.swift | 2 ++ Sources/FoundationNetworking/URLProtectionSpace.swift | 2 ++ Sources/FoundationNetworking/URLRequest.swift | 1 + .../URLSession/URLSessionConfiguration.swift | 9 ++++++--- .../URLSession/URLSessionTaskMetrics.swift | 1 + 7 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Sources/Foundation/NSError.swift b/Sources/Foundation/NSError.swift index 9543fb0c56..5d9d78672f 100644 --- a/Sources/Foundation/NSError.swift +++ b/Sources/Foundation/NSError.swift @@ -803,6 +803,7 @@ extension URLError { } /// The string for the URL which caused a load to fail. + @available(swift, deprecated: 6.1, message: "Use failingURL instead") public var failureURLString: String? { return _nsUserInfo[NSURLErrorFailingURLStringErrorKey] as? String } diff --git a/Sources/Foundation/NSURLError.swift b/Sources/Foundation/NSURLError.swift index a2fbb62b60..a3133962e1 100644 --- a/Sources/Foundation/NSURLError.swift +++ b/Sources/Foundation/NSURLError.swift @@ -20,6 +20,7 @@ public let NSURLErrorFailingURLErrorKey: String = "NSErrorFailingURLKey" /// The `NSError` userInfo dictionary key used to store and retrieve the NSString /// object for the URL which caused a load to fail. +@available(swift, deprecated: 6.1, message: "Use NSURLErrorFailingURLErrorKey instead") public let NSURLErrorFailingURLStringErrorKey: String = "NSErrorFailingURLStringKey" /// The `NSError` userInfo dictionary key used to store and retrieve the diff --git a/Sources/FoundationNetworking/NSURLRequest.swift b/Sources/FoundationNetworking/NSURLRequest.swift index cdda7bcadd..a0d179863c 100644 --- a/Sources/FoundationNetworking/NSURLRequest.swift +++ b/Sources/FoundationNetworking/NSURLRequest.swift @@ -373,6 +373,7 @@ open class NSURLRequest : NSObject, NSSecureCoding, NSCopying, NSMutableCopying open internal(set) var httpShouldHandleCookies: Bool = true + @available(swift, deprecated: 6.1, message: "HTTP/1 pipelining has known compatibility issues, please adopt HTTP/2 and HTTP/3 instead") open internal(set) var httpShouldUsePipelining: Bool = true open override var description: String { @@ -573,6 +574,7 @@ open class NSMutableURLRequest : NSURLRequest { set { super.httpShouldHandleCookies = newValue } } + @available(swift, deprecated: 6.1, message: "HTTP/1 pipelining has known compatibility issues, please adopt HTTP/2 and HTTP/3 instead") open override var httpShouldUsePipelining: Bool { get { return super.httpShouldUsePipelining } set { super.httpShouldUsePipelining = newValue } diff --git a/Sources/FoundationNetworking/URLProtectionSpace.swift b/Sources/FoundationNetworking/URLProtectionSpace.swift index 6470657bc5..26dcc234cf 100644 --- a/Sources/FoundationNetworking/URLProtectionSpace.swift +++ b/Sources/FoundationNetworking/URLProtectionSpace.swift @@ -29,6 +29,7 @@ public let NSURLProtectionSpaceHTTPS: String = "NSURLProtectionSpaceHTTPS" @const NSURLProtectionSpaceFTP @abstract The protocol for FTP */ +@available(swift, deprecated: 6.1, message: "FTP is deprecated") public let NSURLProtectionSpaceFTP: String = "NSURLProtectionSpaceFTP" /*! @@ -47,6 +48,7 @@ public let NSURLProtectionSpaceHTTPSProxy: String = "NSURLProtectionSpaceHTTPSPr @const NSURLProtectionSpaceFTPProxy @abstract The proxy type for ftp proxies */ +@available(swift, deprecated: 6.1, message: "FTP is deprecated") public let NSURLProtectionSpaceFTPProxy: String = "NSURLProtectionSpaceFTPProxy" /*! diff --git a/Sources/FoundationNetworking/URLRequest.swift b/Sources/FoundationNetworking/URLRequest.swift index f8ab4c8c7d..e87201e528 100644 --- a/Sources/FoundationNetworking/URLRequest.swift +++ b/Sources/FoundationNetworking/URLRequest.swift @@ -224,6 +224,7 @@ public struct URLRequest : ReferenceConvertible, Equatable, Hashable, Sendable { /// `true` if the receiver should transmit before the previous response /// is received. `false` if the receiver should wait for the previous response /// before transmitting. + @available(swift, deprecated: 6.1, message: "HTTP/1 pipelining has known compatibility issues, please adopt HTTP/2 and HTTP/3 instead") public var httpShouldUsePipelining: Bool { get { return _handle.map { $0.httpShouldUsePipelining } diff --git a/Sources/FoundationNetworking/URLSession/URLSessionConfiguration.swift b/Sources/FoundationNetworking/URLSession/URLSessionConfiguration.swift index 9236854f4c..89bb774dd7 100644 --- a/Sources/FoundationNetworking/URLSession/URLSessionConfiguration.swift +++ b/Sources/FoundationNetworking/URLSession/URLSessionConfiguration.swift @@ -204,6 +204,7 @@ open class URLSessionConfiguration : NSObject, NSCopying, @unchecked Sendable { */ /* Allow the use of HTTP pipelining */ + @available(swift, deprecated: 6.1, message: "HTTP/1 pipelining has known compatibility issues, please adopt HTTP/2 and HTTP/3 instead") open var httpShouldUsePipelining: Bool /* Allow the session to set cookies on requests */ @@ -229,9 +230,7 @@ open class URLSessionConfiguration : NSObject, NSCopying, @unchecked Sendable { /* The URL resource cache, or nil to indicate that no caching is to be performed */ open var urlCache: URLCache? - /* Enable extended background idle mode for any tcp sockets created. Enabling this mode asks the system to keep the socket open - * and delay reclaiming it when the process moves to the background (see https://developer.apple.com/library/ios/technotes/tn2277/_index.html) - */ + @available(swift, deprecated: 6.1, message: "Not supported") open var shouldUseExtendedBackgroundIdleMode: Bool /* An optional array of Class objects which subclass URLProtocol. @@ -253,6 +252,10 @@ open class URLSessionConfiguration : NSObject, NSCopying, @unchecked Sendable { @available(*, unavailable, message: "Not available on non-Darwin platforms") open var multipathServiceType: URLSessionConfiguration.MultipathServiceType { NSUnsupported() } + /* Uses the classic network loader */ + @available(*, unavailable, message: "Not available on non-Darwin platforms") + open var usesClassicLoadingMode: Bool { NSUnsupported() } + } @available(*, unavailable, message: "Not available on non-Darwin platforms") diff --git a/Sources/FoundationNetworking/URLSession/URLSessionTaskMetrics.swift b/Sources/FoundationNetworking/URLSession/URLSessionTaskMetrics.swift index 5de19fdeef..eaa0cdd030 100644 --- a/Sources/FoundationNetworking/URLSession/URLSessionTaskMetrics.swift +++ b/Sources/FoundationNetworking/URLSession/URLSessionTaskMetrics.swift @@ -29,6 +29,7 @@ open class URLSessionTaskMetrics : NSObject, @unchecked Sendable { public enum ResourceFetchType: Int, Sendable { case unknown = 0 case networkLoad = 1 + @available(swift, deprecated: 6.1, message: "Server push is not supported") case serverPush = 2 case localCache = 3 } From 12f20267797f7e59156fea616f51b1949213783a Mon Sep 17 00:00:00 2001 From: finagolfin Date: Tue, 25 Feb 2025 00:35:50 +0530 Subject: [PATCH 6/9] Remove incorrect `guard` check for Android (#5171) (#5175) --- Sources/Foundation/Process.swift | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Sources/Foundation/Process.swift b/Sources/Foundation/Process.swift index 7d6a1a3952..1ed8a50b52 100644 --- a/Sources/Foundation/Process.swift +++ b/Sources/Foundation/Process.swift @@ -942,13 +942,6 @@ open class Process: NSObject, @unchecked Sendable { 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))) From 0b8ed50c4a8b4bec2408a9101567086eb48b3a60 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Sat, 1 Mar 2025 21:33:37 -0800 Subject: [PATCH 7/9] CoreFoundation: adjust declaration of private SPI The SPI declaration for `libdispatch_init` was not attribtued properly. The result of this omission was an improper reference to the function on Windows when disaptch is _not_ linked statically. Correct the declaration by re-using the `DISPATCH_EXPORT` macro to decorate the declaration with the appropriate DLLStorage as necessary. This was caught by running the Foundation tests with SPM with a refactoring of the toolchain layout during the build. (cherry picked from commit 853b68167d1ea012b732aa19eecebfbd9e3b10fd) --- Sources/CoreFoundation/CFRuntime.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Sources/CoreFoundation/CFRuntime.c b/Sources/CoreFoundation/CFRuntime.c index 11c20ff0c1..3336852904 100644 --- a/Sources/CoreFoundation/CFRuntime.c +++ b/Sources/CoreFoundation/CFRuntime.c @@ -45,6 +45,10 @@ OBJC_EXPORT void *objc_destructInstance(id obj); #include #endif +#if __HAS_DISPATCH__ && !TARGET_OS_MAC +#include +#endif + enum { // retain/release recording constants -- must match values // used by OA for now; probably will change in the future @@ -1165,8 +1169,8 @@ CF_EXPORT CF_PRIVATE os_unfair_recursive_lock CFPlugInGlobalDataLock; -#if __HAS_DISPATCH__ -extern void libdispatch_init(); +#if __HAS_DISPATCH__ && !TARGET_OS_MAC +DISPATCH_EXPORT void libdispatch_init(); #endif void __CFInitialize(void) { From 721eabc9ea71d949e1ceab65ab3d45ecb12f3064 Mon Sep 17 00:00:00 2001 From: Johannes Weiss Date: Mon, 3 Mar 2025 23:29:12 +0000 Subject: [PATCH 8/9] always @preconcurrency import Glibc/Musl/Android/Bionic/WASILibc [6.1] (#5177) --- Sources/Foundation/CGFloat.swift | 2 +- Sources/Foundation/FileHandle.swift | 8 ++++---- Sources/Foundation/FileManager+POSIX.swift | 4 ++-- Sources/Foundation/FileManager.swift | 4 ++-- Sources/Foundation/Host.swift | 2 +- Sources/Foundation/NSData.swift | 2 +- Sources/Foundation/NSError.swift | 4 ++-- Sources/Foundation/NSLock.swift | 4 ++-- Sources/Foundation/NSPathUtilities.swift | 4 ++-- Sources/Foundation/NSPlatform.swift | 2 +- Sources/Foundation/NSSwiftRuntime.swift | 8 ++++---- Sources/Foundation/NSURL.swift | 6 +++--- Sources/Foundation/Port.swift | 8 ++++---- Sources/Foundation/Process.swift | 2 +- Sources/Foundation/Thread.swift | 6 +++--- Sources/FoundationNetworking/HTTPCookie.swift | 2 +- Sources/Testing/Testing.swift | 8 ++++---- Sources/XCTest/Public/XCTestMain.swift | 2 +- Sources/plutil/main.swift | 6 +++--- Sources/xdgTestHelper/main.swift | 2 +- 20 files changed, 43 insertions(+), 43 deletions(-) diff --git a/Sources/Foundation/CGFloat.swift b/Sources/Foundation/CGFloat.swift index c59977f88a..425ab259fe 100644 --- a/Sources/Foundation/CGFloat.swift +++ b/Sources/Foundation/CGFloat.swift @@ -8,7 +8,7 @@ // #if canImport(Android) -import Android +@preconcurrency import Android #endif @frozen diff --git a/Sources/Foundation/FileHandle.swift b/Sources/Foundation/FileHandle.swift index 7a985f2ef8..35c8eda476 100644 --- a/Sources/Foundation/FileHandle.swift +++ b/Sources/Foundation/FileHandle.swift @@ -20,22 +20,22 @@ fileprivate let _read = Darwin.read(_:_:_:) fileprivate let _write = Darwin.write(_:_:_:) fileprivate let _close = Darwin.close(_:) #elseif canImport(Glibc) -import Glibc +@preconcurrency import Glibc fileprivate let _read = Glibc.read(_:_:_:) fileprivate let _write = Glibc.write(_:_:_:) fileprivate let _close = Glibc.close(_:) #elseif canImport(Musl) -import Musl +@preconcurrency import Musl fileprivate let _read = Musl.read(_:_:_:) fileprivate let _write = Musl.write(_:_:_:) fileprivate let _close = Musl.close(_:) #elseif canImport(WASILibc) -import WASILibc +@preconcurrency import WASILibc fileprivate let _read = WASILibc.read(_:_:_:) fileprivate let _write = WASILibc.write(_:_:_:) fileprivate let _close = WASILibc.close(_:) #elseif canImport(Android) -import Android +@preconcurrency import Android fileprivate let _read = Android.read(_:_:_:) fileprivate let _write = Android.write(_:_:_:) fileprivate let _close = Android.close(_:) diff --git a/Sources/Foundation/FileManager+POSIX.swift b/Sources/Foundation/FileManager+POSIX.swift index 89bc95b101..cbd3659308 100644 --- a/Sources/Foundation/FileManager+POSIX.swift +++ b/Sources/Foundation/FileManager+POSIX.swift @@ -8,7 +8,7 @@ #if !os(Windows) #if canImport(Android) -import Android +@preconcurrency import Android #endif #if os(Android) && (arch(i386) || arch(arm)) // struct stat.st_mode is UInt32 @@ -21,7 +21,7 @@ internal func &(left: UInt32, right: mode_t) -> mode_t { internal import Synchronization #if os(WASI) -import WASILibc +@preconcurrency import WASILibc // wasi-libc defines the following constants in a way that Clang Importer can't // understand, so we need to grab them manually through ForSwiftFoundationOnly.h internal var DT_DIR: UInt8 { _getConst_DT_DIR() } diff --git a/Sources/Foundation/FileManager.swift b/Sources/Foundation/FileManager.swift index c28ee293b7..029e95dcbd 100644 --- a/Sources/Foundation/FileManager.swift +++ b/Sources/Foundation/FileManager.swift @@ -20,9 +20,9 @@ import WinSDK #endif #if os(WASI) -import WASILibc +@preconcurrency import WASILibc #elseif canImport(Bionic) -import Bionic +@preconcurrency import Bionic #endif #if os(Windows) diff --git a/Sources/Foundation/Host.swift b/Sources/Foundation/Host.swift index fb13063121..6e737d0014 100644 --- a/Sources/Foundation/Host.swift +++ b/Sources/Foundation/Host.swift @@ -13,7 +13,7 @@ import WinSDK #endif #if canImport(Android) - import Android + @preconcurrency import Android // Android Bionic differs a little with respect to the Linux Glibc. // IFF_LOOPBACK is part of the enumeration net_device_flags, which needs to diff --git a/Sources/Foundation/NSData.swift b/Sources/Foundation/NSData.swift index 65eb0d93e2..1a076beff7 100644 --- a/Sources/Foundation/NSData.swift +++ b/Sources/Foundation/NSData.swift @@ -12,7 +12,7 @@ import Dispatch #endif #if canImport(Android) -import Android +@preconcurrency import Android #endif extension NSData { diff --git a/Sources/Foundation/NSError.swift b/Sources/Foundation/NSError.swift index 5d9d78672f..d6a4d1868c 100644 --- a/Sources/Foundation/NSError.swift +++ b/Sources/Foundation/NSError.swift @@ -13,11 +13,11 @@ #if canImport(Darwin) import Darwin #elseif canImport(Glibc) -import Glibc +@preconcurrency import Glibc #elseif canImport(CRT) import CRT #elseif canImport(Android) -import Android +@preconcurrency import Android #endif @_implementationOnly import CoreFoundation diff --git a/Sources/Foundation/NSLock.swift b/Sources/Foundation/NSLock.swift index 9d0fadc910..a60eff1535 100644 --- a/Sources/Foundation/NSLock.swift +++ b/Sources/Foundation/NSLock.swift @@ -10,9 +10,9 @@ @_implementationOnly import CoreFoundation #if canImport(Glibc) -import Glibc +@preconcurrency import Glibc #elseif canImport(Bionic) -import Bionic +@preconcurrency import Bionic #endif #if os(Windows) diff --git a/Sources/Foundation/NSPathUtilities.swift b/Sources/Foundation/NSPathUtilities.swift index ba8a48fad3..9b74edc5c7 100644 --- a/Sources/Foundation/NSPathUtilities.swift +++ b/Sources/Foundation/NSPathUtilities.swift @@ -11,9 +11,9 @@ #if os(Windows) import WinSDK #elseif canImport(Android) -import Android +@preconcurrency import Android #elseif os(WASI) -import WASILibc +@preconcurrency import WASILibc #endif #if os(Windows) diff --git a/Sources/Foundation/NSPlatform.swift b/Sources/Foundation/NSPlatform.swift index 5424f5bb92..026a410e67 100644 --- a/Sources/Foundation/NSPlatform.swift +++ b/Sources/Foundation/NSPlatform.swift @@ -11,7 +11,7 @@ fileprivate let _NSPageSize = Int(vm_page_size) #elseif os(Linux) || os(Android) || os(OpenBSD) #if canImport(Android) -import Android +@preconcurrency import Android #endif fileprivate let _NSPageSize = Int(getpagesize()) #elseif os(Windows) diff --git a/Sources/Foundation/NSSwiftRuntime.swift b/Sources/Foundation/NSSwiftRuntime.swift index 1509c31d71..727d343f28 100644 --- a/Sources/Foundation/NSSwiftRuntime.swift +++ b/Sources/Foundation/NSSwiftRuntime.swift @@ -16,13 +16,13 @@ internal import Synchronization #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) @_exported import Darwin #elseif canImport(Glibc) -@_exported import Glibc +@_exported @preconcurrency import Glibc #elseif canImport(Musl) -@_exported import Musl +@_exported @preconcurrency import Musl #elseif canImport(Bionic) -@_exported import Bionic +@_exported @preconcurrency import Bionic #elseif os(WASI) -@_exported import WASILibc +@_exported @preconcurrency import WASILibc #elseif os(Windows) @_exported import CRT #endif diff --git a/Sources/Foundation/NSURL.swift b/Sources/Foundation/NSURL.swift index a9972c1ac2..88f6cd1108 100644 --- a/Sources/Foundation/NSURL.swift +++ b/Sources/Foundation/NSURL.swift @@ -19,11 +19,11 @@ internal let kCFURLWindowsPathStyle = CFURLPathStyle.cfurlWindowsPathStyle #if canImport(Darwin) import Darwin #elseif canImport(Glibc) -import Glibc +@preconcurrency import Glibc #elseif canImport(Musl) -import Musl +@preconcurrency import Musl #elseif canImport(Bionic) -import Bionic +@preconcurrency import Bionic #endif // NOTE: this represents PLATFORM_PATH_STYLE diff --git a/Sources/Foundation/Port.swift b/Sources/Foundation/Port.swift index 2185836818..588d6b6577 100644 --- a/Sources/Foundation/Port.swift +++ b/Sources/Foundation/Port.swift @@ -108,19 +108,19 @@ fileprivate let FOUNDATION_IPPROTO_TCP = IPPROTO_TCP #endif #if canImport(Glibc) && !os(OpenBSD) -import Glibc +@preconcurrency import Glibc fileprivate let FOUNDATION_SOCK_STREAM = Int32(SOCK_STREAM.rawValue) fileprivate let FOUNDATION_IPPROTO_TCP = Int32(IPPROTO_TCP) #endif #if canImport(Musl) -import Musl +@preconcurrency import Musl fileprivate let FOUNDATION_SOCK_STREAM = Int32(SOCK_STREAM) fileprivate let FOUNDATION_IPPROTO_TCP = Int32(IPPROTO_TCP) #endif #if canImport(Glibc) && os(OpenBSD) -import Glibc +@preconcurrency import Glibc fileprivate let FOUNDATION_SOCK_STREAM = Int32(SOCK_STREAM) fileprivate let FOUNDATION_IPPROTO_TCP = Int32(IPPROTO_TCP) fileprivate let INADDR_ANY: in_addr_t = 0 @@ -128,7 +128,7 @@ fileprivate let INADDR_LOOPBACK = 0x7f000001 #endif #if canImport(Android) -import Android +@preconcurrency import Android fileprivate let FOUNDATION_SOCK_STREAM = Int32(Android.SOCK_STREAM) fileprivate let FOUNDATION_IPPROTO_TCP = Int32(Android.IPPROTO_TCP) fileprivate let INADDR_ANY: in_addr_t = 0 diff --git a/Sources/Foundation/Process.swift b/Sources/Foundation/Process.swift index 1ed8a50b52..07b9be12fd 100644 --- a/Sources/Foundation/Process.swift +++ b/Sources/Foundation/Process.swift @@ -19,7 +19,7 @@ import struct WinSDK.HANDLE #if canImport(Darwin) import Darwin #elseif canImport(Android) -import Android +@preconcurrency import Android #endif internal import Synchronization diff --git a/Sources/Foundation/Thread.swift b/Sources/Foundation/Thread.swift index 0985a4826d..a62dfa28d6 100644 --- a/Sources/Foundation/Thread.swift +++ b/Sources/Foundation/Thread.swift @@ -14,11 +14,11 @@ import WinSDK #endif #if canImport(Glibc) -import Glibc +@preconcurrency import Glibc #elseif canImport(Musl) -import Musl +@preconcurrency import Musl #elseif canImport(Bionic) -import Bionic +@preconcurrency import Bionic #endif // WORKAROUND_SR9811 diff --git a/Sources/FoundationNetworking/HTTPCookie.swift b/Sources/FoundationNetworking/HTTPCookie.swift index 237c1daf55..18a62776bb 100644 --- a/Sources/FoundationNetworking/HTTPCookie.swift +++ b/Sources/FoundationNetworking/HTTPCookie.swift @@ -16,7 +16,7 @@ import Foundation #if os(Windows) import WinSDK #elseif canImport(Android) -import Android +@preconcurrency import Android #endif public struct HTTPCookiePropertyKey : RawRepresentable, Equatable, Hashable, Sendable { diff --git a/Sources/Testing/Testing.swift b/Sources/Testing/Testing.swift index 2483c14ed6..a8a40f1d58 100644 --- a/Sources/Testing/Testing.swift +++ b/Sources/Testing/Testing.swift @@ -8,13 +8,13 @@ // #if canImport(Glibc) -import Glibc +@preconcurrency import Glibc #elseif canImport(Musl) -import Musl +@preconcurrency import Musl #elseif canImport(Bionic) -import Bionic +@preconcurrency import Bionic #elseif os(WASI) -import WASILibc +@preconcurrency import WASILibc #elseif canImport(CRT) import CRT #endif diff --git a/Sources/XCTest/Public/XCTestMain.swift b/Sources/XCTest/Public/XCTestMain.swift index e19184e69f..2cfefbdbb5 100644 --- a/Sources/XCTest/Public/XCTestMain.swift +++ b/Sources/XCTest/Public/XCTestMain.swift @@ -27,7 +27,7 @@ #if canImport(Darwin) import Darwin #elseif canImport(Glibc) - import Glibc + @preconcurrency import Glibc #endif /// Starts a test run for the specified test cases. diff --git a/Sources/plutil/main.swift b/Sources/plutil/main.swift index 29584596d3..34b1d5e332 100644 --- a/Sources/plutil/main.swift +++ b/Sources/plutil/main.swift @@ -11,13 +11,13 @@ import Darwin import SwiftFoundation #elseif canImport(Glibc) import Foundation -import Glibc +@preconcurrency import Glibc #elseif canImport(Musl) import Foundation -import Musl +@preconcurrency import Musl #elseif canImport(Bionic) import Foundation -import Bionic +@preconcurrency import Bionic #elseif canImport(CRT) import Foundation import CRT diff --git a/Sources/xdgTestHelper/main.swift b/Sources/xdgTestHelper/main.swift index fb037e2435..769ac33882 100644 --- a/Sources/xdgTestHelper/main.swift +++ b/Sources/xdgTestHelper/main.swift @@ -20,7 +20,7 @@ import FoundationNetworking #if os(Windows) import WinSDK #elseif canImport(Android) -import Android +@preconcurrency import Android #endif enum HelperCheckStatus : Int32 { From 21bb65e6560262dcc82a73b4429090bc85bc4f82 Mon Sep 17 00:00:00 2001 From: Hiroshi Yamauchi <56735936+hjyamauchi@users.noreply.github.com> Date: Thu, 6 Mar 2025 01:57:40 -0800 Subject: [PATCH 9/9] Process: unwrap the posix_spawnattr_t on Android (#5185) This is required as while `posix_spawnattr_init` permits a nullable type, `posix_spawnattr_setflags` properly expects a non-null parameter. Unwrap the newly minted spawnattr or abort if the allocation failed. Cherry pick commit https://github.com/swiftlang/swift-corelibs-foundation/pull/5179 --- Sources/Foundation/Process.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Sources/Foundation/Process.swift b/Sources/Foundation/Process.swift index 07b9be12fd..6baa2e2c0e 100644 --- a/Sources/Foundation/Process.swift +++ b/Sources/Foundation/Process.swift @@ -944,6 +944,12 @@ open class Process: NSObject, @unchecked Sendable { var spawnAttrs: posix_spawnattr_t = posix_spawnattr_t() #endif try _throwIfPosixError(posix_spawnattr_init(&spawnAttrs)) +#if os(Android) + guard var spawnAttrs else { + throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno), + userInfo: [NSURLErrorKey:self.executableURL!]) + } +#endif try _throwIfPosixError(posix_spawnattr_setflags(&spawnAttrs, .init(POSIX_SPAWN_SETPGROUP))) #if canImport(Darwin) try _throwIfPosixError(posix_spawnattr_setflags(&spawnAttrs, .init(POSIX_SPAWN_CLOEXEC_DEFAULT)))