Skip to content

Commit

Permalink
Foundation: repair the build for Android API level 28+
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
compnerd committed Feb 29, 2024
1 parent dbca8c7 commit b3c8ce0
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Sources/Foundation/FileHandle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down
24 changes: 14 additions & 10 deletions Sources/Foundation/FileManager+POSIX.swift
Original file line number Diff line number Diff line change
Expand Up @@ -744,29 +744,31 @@ extension FileManager {
let ps = UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>.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<CChar>.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
}

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:
Expand Down Expand Up @@ -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<CChar>.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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions Sources/Foundation/FileManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/Foundation/Host.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import WinSDK
}

// getnameinfo uses size_t for its 4th and 6th arguments.
private func getnameinfo(_ addr: UnsafePointer<sockaddr>?, _ addrlen: socklen_t, _ host: UnsafeMutablePointer<Int8>?, _ hostlen: socklen_t, _ serv: UnsafeMutablePointer<Int8>?, _ servlen: socklen_t, _ flags: Int32) -> Int32 {
private func getnameinfo(_ addr: UnsafePointer<sockaddr>, _ addrlen: socklen_t, _ host: UnsafeMutablePointer<Int8>?, _ hostlen: socklen_t, _ serv: UnsafeMutablePointer<Int8>?, _ servlen: socklen_t, _ flags: Int32) -> Int32 {
return Glibc.getnameinfo(addr, addrlen, host, Int(hostlen), serv, Int(servlen), flags)
}

Expand Down
7 changes: 7 additions & 0 deletions Sources/Foundation/Process.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down

0 comments on commit b3c8ce0

Please sign in to comment.