Skip to content
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

Closed
wants to merge 1 commit into from

Conversation

finagolfin
Copy link
Member

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.

return NSData.NSDataReadResult(bytes: data, length: mapSize) { buffer, length in
munmap(buffer, length)
}
#else
return NSData.NSDataReadResult(bytes: data!, length: mapSize) { buffer, length in
Copy link
Member Author

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.

Copy link
Contributor

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.

@parkera
Copy link
Contributor

parkera commented Dec 1, 2023

@swift-ci test

return NSData.NSDataReadResult(bytes: data, length: mapSize) { buffer, length in
munmap(buffer, length)
}
#else
return NSData.NSDataReadResult(bytes: data!, length: mapSize) { buffer, length in
Copy link
Contributor

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)
Copy link
Contributor

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?

Copy link
Member Author

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?

Copy link

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.

Copy link
Member Author

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.

Copy link

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>!]

Copy link
Member Author

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

Copy link
Member Author

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()?

Copy link
Member

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.

Copy link
Member Author

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.
Copy link
Member Author

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?

@finagolfin
Copy link
Member Author

@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)
Copy link
Member

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?

Copy link
Member Author

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 {
Copy link
Member

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, removed in #5010, you can add it in a version of #4889 for 6.0.

@@ -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)
Copy link
Member

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 {
Copy link
Member

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's better, dropped this in #5010, you can do that in a version of #4889 for 6.0.

@@ -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 }
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the signature would work too, dropped this in #5010, you can submit it in a version of #4889 for 6.0.

@finagolfin
Copy link
Member Author

Now that swift-foundation was merged, this pull no longer applies cleanly to that rewrite. Instead, I have modified or removed portions of this pull based on the review comments here and applied it to the release/6.0 branch in #5010 instead, where swift-foundation will presumably not be merged also.

Once that's in 6.0, I will rework this pull for swift-foundation and make the necessary changes here also. My answers to the review comments above will now address what I changed for #5010.

@finagolfin
Copy link
Member Author

Some of these are no longer needed after the re-core and other changes, others have been submitted again in #5024 and my pull for that, hyp#1.

@finagolfin finagolfin closed this Aug 11, 2024
@finagolfin finagolfin deleted the droid branch August 11, 2024 02:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants