From 9e44c649b4bb33b2ea507b3b9e317d20daea6966 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Mon, 30 Jun 2025 16:52:47 -0700 Subject: [PATCH] Work around Android nullability errors Motivation: Android messed up their nullability annotations in fts_open. The original change in https://android.googlesource.com/platform/bionic/+/dec8efd72a6ad8b807a15a614ae1519487cfa456 asserted that fts_open's path argument took a non-null pointer to an array of non-null pointers to strings. That's challenging, because the _end_ of that array is indicated by a null pointer. Regardless, this was eventually fixed in https://android.googlesource.com/platform/bionic/+/da81ec4d1cbd0279014feb60535bf38defcd9346. Unfortunately, that was more than a year after the offending change, so we need to work around it. Modifications: Add a shim for Android that omits the nullability annotations. Use that shim on Android. Result: Android works again. Resolves #3273. --- Sources/CNIOLinux/include/CNIOLinux.h | 3 +++ Sources/CNIOLinux/shim.c | 4 ++++ Sources/NIOFileSystem/Internal/System Calls/Syscalls.swift | 7 +++++++ 3 files changed, 14 insertions(+) diff --git a/Sources/CNIOLinux/include/CNIOLinux.h b/Sources/CNIOLinux/include/CNIOLinux.h index 311b3b85440..04630d8cf92 100644 --- a/Sources/CNIOLinux/include/CNIOLinux.h +++ b/Sources/CNIOLinux/include/CNIOLinux.h @@ -149,5 +149,8 @@ extern const unsigned long CNIOLinux_UTIME_NOW; extern const long CNIOLinux_UDP_MAX_SEGMENTS; +// A workaround for incorrect nullability annotations in the Android SDK. +FTS *CNIOLinux_fts_open(char * const *path_argv, int options, int (*compar)(const FTSENT **, const FTSENT **)); + #endif #endif diff --git a/Sources/CNIOLinux/shim.c b/Sources/CNIOLinux/shim.c index 955c440063c..afbad100c51 100644 --- a/Sources/CNIOLinux/shim.c +++ b/Sources/CNIOLinux/shim.c @@ -220,4 +220,8 @@ const unsigned long CNIOLinux_UTIME_NOW = UTIME_NOW; const long CNIOLinux_UDP_MAX_SEGMENTS = UDP_MAX_SEGMENTS; #endif const long CNIOLinux_UDP_MAX_SEGMENTS = -1; + +FTS *CNIOLinux_fts_open(char * const *path_argv, int options, int (*compar)(const FTSENT **, const FTSENT **)) { + fts_open(path_argv, options, compar); +} #endif diff --git a/Sources/NIOFileSystem/Internal/System Calls/Syscalls.swift b/Sources/NIOFileSystem/Internal/System Calls/Syscalls.swift index c98bc1ed231..a8718760258 100644 --- a/Sources/NIOFileSystem/Internal/System Calls/Syscalls.swift +++ b/Sources/NIOFileSystem/Internal/System Calls/Syscalls.swift @@ -456,7 +456,14 @@ internal func libc_fts_open( _ path: [UnsafeMutablePointer?], _ options: CInt ) -> UnsafeMutablePointer { + #if os(Android) + // This branch is a workaround for incorrect nullability annotations in the Android SDK. + // They were added in https://android.googlesource.com/platform/bionic/+/dec8efd72a6ad8b807a15a614ae1519487cfa456, + // and lasted for more than a year: https://android.googlesource.com/platform/bionic/+/da81ec4d1cbd0279014feb60535bf38defcd9346. + CNIOLinux_fts_open(path, options, nil)! + #else fts_open(path, options, nil)! + #endif } /// fts(3)