Skip to content

Commit d011634

Browse files
authored
Build fixes to allow using the epoll native transport on Android (#16016)
**Note**: more details are provided in the single commit messages. ## Motivation: the epoll native transport currently fails to compile on Android, due to a couple of compilation failures ``` transport-native-unix-common/src/main/c/netty_unix_errors.c:47:15: error: incompatible integer to pointer conversion initializing 'char *' with an expression of type 'int' [-Wint-conversion] 47 | char* tmp = strerror_r(errnum, strerrbuf, buflen); | ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` and ``` transport-native-unix-common/src/main/c/netty_unix_socket.c:449:9: error: call to undeclared library function 'bzero' with type 'void (void *, unsigned long)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 449 | bzero(&addr, sizeof(addr)); // Zap addr so we can strlen(addr.sun_path) later. See unix(4). | ^ transport-native-unix-common/src/main/c/netty_unix_socket.c:449:9: note: include the header <strings.h> or explicitly provide a declaration for 'bzero' ``` - `netty_unix_socket.c` uses `bzero` (in a single place). `bzero` is defined in `strings.h`, which however does not seem to be pulled in by default in Android with the current includes. Moreover, `bzero` is deprecated and was dropped in POSIX 2018. See [POSIX 2018 docs](https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap03.html) and [relevant AOSP 16 code](https://cs.android.com/android/platform/superproject/+/android16-release:bionic/libc/include/strings.h;l=69). - `netty_unix_errors.c` currently uses the GNU `strerror_r` on Android. Android, however, only exposes the GNU `strerror_r` when `_GNU_SOURCE` is defined and only on API level 23+. See [relevant AOSP 16 code](https://cs.android.com/android/platform/superproject/+/android16-release:bionic/libc/include/string.h;l=145?q=string.h) ## Modification: - a [dedicated repository](https://github.com/faenil/NettyEpollAndroidBuildFailureTest) was spun up to allow reproducing the build failures - it is an Android project containing the necessary plumbing to build the epoll native transport - it can be easily built by following the instructions in the `README` in the project repo - replace the deprecated `bzero` with `memset`, already used for the very same purpose in many places in the same file. - use the XSI `strerror_r` on Android, when `_GNU_SOURCE` is not defined ## Result: - epoll native transport builds and `Epoll.ensureAvailability()` succeeds on Android. Tested on Android 16 emulator image `BP41.250916.009.A1` (x86_64), NDK `27.0.12077973`
1 parent 14fc741 commit d011634

2 files changed

Lines changed: 5 additions & 2 deletions

File tree

transport-native-unix-common/src/main/c/netty_unix_errors.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,11 @@ static jmethodID closedChannelExceptionMethodId = NULL;
3737
even on platforms where the GNU variant is exposed.
3838
Note: `strerrbuf` must be initialized to all zeros prior to calling this function.
3939
XSI or GNU functions do not have such a requirement, but our wrappers do.
40+
41+
Android exposes the XSI variant by default, see
42+
https://cs.android.com/android/platform/superproject/+/android16-release:bionic/libc/include/string.h;l=145?q=string.h
4043
*/
41-
#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 || __APPLE__) && ! _GNU_SOURCE
44+
#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 || __APPLE__ || __ANDROID__) && ! _GNU_SOURCE
4245
static inline int strerror_r_xsi(int errnum, char *strerrbuf, size_t buflen) {
4346
return strerror_r(errnum, strerrbuf, buflen);
4447
}

transport-native-unix-common/src/main/c/netty_unix_socket.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ static jobject _recvFromDomainSocket(JNIEnv* env, jint fd, void* buffer, jint po
458458
int err;
459459

460460
do {
461-
bzero(&addr, sizeof(addr)); // Zap addr so we can strlen(addr.sun_path) later. See unix(4).
461+
memset(&addr, 0, sizeof(addr)); // Zap addr so we can strlen(addr.sun_path) later. See unix(4).
462462
res = recvfrom(fd, buffer + pos, (size_t) (limit - pos), 0, (struct sockaddr*) &addr, &addrlen);
463463
// Keep on reading if it was interrupted
464464
} while (res == -1 && ((err = errno) == EINTR));

0 commit comments

Comments
 (0)