-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Android: add better nullability checks for nullability annotations added in NDK 26 #4850
Conversation
Sources/Foundation/FileHandle.swift
Outdated
return NSData.NSDataReadResult(bytes: data, length: mapSize) { buffer, length in | ||
munmap(buffer, length) | ||
} | ||
#else | ||
return NSData.NSDataReadResult(bytes: data!, length: mapSize) { buffer, length in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As shown in my Bionic link above, mmap()
now returns _Nonnull
, so this force-unwrap fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels rather unfortunate to ifdef around this here instead of at the place we call mmap
.
@swift-ci test |
Sources/Foundation/FileHandle.swift
Outdated
return NSData.NSDataReadResult(bytes: data, length: mapSize) { buffer, length in | ||
munmap(buffer, length) | ||
} | ||
#else | ||
return NSData.NSDataReadResult(bytes: data!, length: mapSize) { buffer, length in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels rather unfortunate to ifdef around this here instead of at the place we call mmap
.
@@ -1085,10 +1091,18 @@ extension FileManager { | |||
do { | |||
guard fm.fileExists(atPath: _url.path) else { throw _NSErrorWithErrno(ENOENT, reading: true, url: url) } | |||
_stream = try FileManager.default._fileSystemRepresentation(withPath: _url.path) { fsRep in | |||
#if os(Android) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly here, can we do this by converting the type somehow at the call to fts_open
instead of around all uses of the type before that point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe there is, I just don't know how to do it. This is simply the best I came up with after seeing these Swift type-casting issues for the first time, and I wanted to ask if there was a better way.
@glbrntt, you recently added similar code to NIO, wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIO wraps all of the syscalls and does any platform-specific shenanigans within the wrapper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, but that will still require adapting these types for nullability annotations: see my recent patch of your new NIO code for Android.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re: your patch, does using an implicitly unwrapped optional work for both cases? e.g. [UnsafeMutablePointer<CInterop.PlatformChar>!]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get the following error with Swift 5.9.2 on Android AArch64 if I add that to the type signature of libc_fts_open()
:
swift-nio/Sources/NIOFileSystem/Internal/System Calls/Syscalls.swift:407:14: error: using '!' is not allowed here; perhaps '?' was intended?
_ path: [UnsafeMutablePointer<CInterop.PlatformChar>!],
^ ~
?
error: fatalError
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@glbrntt, is that type what you had in mind, or simply unwrapping the arguments when they are passed in inside ftsOpen()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that I approached it similarly to what was being suggested - rebinding the memory around the call site.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These fts_open()
changes were no longer needed after swiftlang/swift#74829, so I removed them in #5010.
@@ -307,10 +307,15 @@ open class FileHandle : NSObject { | |||
if options.contains(.alwaysMapped) { | |||
// Filesizes are often 64bit even on 32bit systems | |||
let mapSize = min(length, Int(clamping: statbuf.st_size)) | |||
#if os(Android) | |||
// Bionic mmap() now returns _Nonnull, so the force unwrap below isn't needed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@parkera, is this the change you had in mind?
@parkera, any further feedback here? |
@@ -741,32 +741,38 @@ extension FileManager { | |||
if rmdir(fsRep) == 0 { | |||
return | |||
} else if errno == ENOTEMPTY { | |||
#if os(Android) | |||
let ps = UnsafeMutablePointer<UnsafeMutablePointer<Int8>>.allocate(capacity: 2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need to duplicate this or can we get away with a rebinding of the memory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No longer needed after your swiftlang/swift#74829, so removed in #5010.
let stream = fts_open(ps, FTS_PHYSICAL | FTS_XDEV | FTS_NOCHDIR | FTS_NOSTAT, nil) | ||
ps.deinitialize(count: 2) | ||
ps.deallocate() | ||
|
||
if stream != nil { | ||
if let openStream = stream { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not simply if let stream
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -1085,10 +1091,18 @@ extension FileManager { | |||
do { | |||
guard fm.fileExists(atPath: _url.path) else { throw _NSErrorWithErrno(ENOENT, reading: true, url: url) } | |||
_stream = try FileManager.default._fileSystemRepresentation(withPath: _url.path) { fsRep in | |||
#if os(Android) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that I approached it similarly to what was being suggested - rebinding the memory around the call site.
@@ -1315,7 +1329,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 let newFS = newItemFS, let origFS = originalFS, rename(newFS, origFS) == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not simply force unwrap?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -25,7 +25,8 @@ 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 { | |||
return Glibc.getnameinfo(addr, addrlen, host, Int(hostlen), serv, Int(servlen), flags) | |||
guard let saddr = addr else { return -1 } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that I prefer my approach of changing the signature of the private func.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry about the delay, been meaning to get to this, hopefully this week.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that Once that's in 6.0, I will rework this pull for |
This is needed because Bionic recently added a bunch of these annotations. I made sure this pull doesn't break anything by testing most of it with the previous NDK 25c also. I used this patch with others to build the Swift toolchain for my Android CI, finagolfin/swift-android-sdk#122, and the Termux app for Android, which now uses NDK 26b.
@drodriguez or @compnerd, please review.