-
Notifications
You must be signed in to change notification settings - Fork 129
Android: update pread/pwrite for nullability annotations in NDK 26 #148
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
Conversation
|
@glessard, would you review? |
|
@swift-ci please test |
| if mockingEnabled { return _mockInt(fd, buf, nbyte, offset) } | ||
| #endif | ||
| return pwrite(fd, buf, nbyte, offset) | ||
| return pwrite(fd, buf!, nbyte, offset) |
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'm afraid we can't do it this way. This pointer comes from a caller-supplied buffer, whose baseAddress could well be nil. For example:
let fd = FileDescriptor.standardOutput
let empty = UnsafeRawBufferPointer(start: nil, count: 0)
let written = try fd.write(toAbsoluteOffset: 0, empty) // crash at runtime with the suggested force-unwrap
We don't have that precise case covered in a test, but we should!
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, I will check it instead.
|
@swift-ci please test |
|
@glessard, I made a different change to this locally, I just need to add the tests you asked for. I will push that here soon and let you know. |
|
No problem! I wasn't sure about the status, and this solution came to mind. |
|
After reading the documentation for these functions in POSIX, I wonder if we should simply return 0 whenever presented with an empty buffer. It is not required to detect errors when |
|
This is what I had so far, I've just been putting off writing the tests: |
|
Returning The posix docs state that an implementation doesn't need to check for errors if |
That's not the issue here though: this issue is that the buffer read or written into cannot be null. That's definitely an error.
Yes, checking the
You can't do anything if the buffer you want to
Oh, that's what you were relying on with this change of yours? I wondered why you were swallowing the error altogether. If you want to rely on that clause, I just tried this pull on Android and it works: I'm fine with merging this. Alternately and after looking into this more, the If you are worried that there might be more internal callers of these |
It would be a programmer error to pass a nil pointer to the call with an expectation that 1 or more bytes be read, but that is not something that will happen here. We are not editing a public function, but an internal one that gets called in a very specific way. That specific way includes throwing an error if the function does not return zero. Also: according to the man page, passing 0 for |
Heh, OK, but you are the one who originally raised that nil pointer concern a couple months ago.
Nah, I am fine with your current approach in this pull, which works on Android too, please go ahead and squash and merge. If you prefer something else, just let me know. |
|
Ping @glessard, anything holding this up? |
|
I'd like to try a different approach, where we can make the syscall regardless on platforms where the parameter has the typical nullability. I don't love the idea of skipping the syscall on android either, fwiw. |
I didn't either, but once you pointed out that "The posix docs state that an implementation doesn't need to check for errors if nbyte is 0, and that made me think that it might be okay to skip the syscall when that happens," I was fine with it. Since we cannot depend on the call to the underlying C function erroring if we pass in that edge case, it's fine to skip that edge case and maybe raise a Swift error ourselves. |
|
@swift-ci please test |
|
@swift-ci please test |
|
Doesn't work: |
|
@swift-ci please test |
finagolfin
left a comment
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.
Compiles and all tests pass again on Android now.
This is needed because Bionic recently added a bunch of these annotations, specifically marking these two buffers as
_Nonnull. I made sure this pull doesn't break anything by testing it on linux x86_64 and with the previous NDK 25c too. I used this patch with others to build the Swift toolchain and this package for my Android CI, finagolfin/swift-android-sdk#122.