From 0c7405cf35b5ebd3ce2f8ebba84c1ea40cf5f6d7 Mon Sep 17 00:00:00 2001 From: Henrique Ferreiro Date: Mon, 22 Jun 2026 14:38:44 +0200 Subject: [PATCH] aosp: Fix GTest output on AOSP. musl flushes stdout/stderr via writev, so wrap it and route STDOUT_FILENO/STDERR_FILENO writes through SbLogRaw, which lands in Android logcat. Bug: 495203133 --- starboard/android/shared/posix_emu/file.cc | 34 +++++++++++++++++++ .../build/config/starboard_target_type.gni | 1 + 2 files changed, 35 insertions(+) diff --git a/starboard/android/shared/posix_emu/file.cc b/starboard/android/shared/posix_emu/file.cc index 973b2596115b..78d3e425c4d2 100644 --- a/starboard/android/shared/posix_emu/file.cc +++ b/starboard/android/shared/posix_emu/file.cc @@ -13,7 +13,10 @@ // limitations under the License. #include +#include +#include +#include #include #include "starboard/android/shared/asset_manager.h" @@ -34,6 +37,7 @@ extern "C" { int __real_close(int fildes); int __real_open(const char* path, int oflag, ...); int __real_openat(int dirfd, const char* path, int oflag, ...); +ssize_t __real_writev(int fd, const struct iovec* iov, int iovcnt); int __wrap_close(int fildes) { AssetManager* asset_manager = AssetManager::GetInstance(); @@ -68,4 +72,34 @@ int __wrap_open(const char* path, int oflag, ...) { return __wrap_openat(AT_FDCWD, path, oflag); } +// Route stdout/stderr writes, which musl flushes via writev, through SbLogRaw +// so they reach Android logcat. +ssize_t __wrap_writev(int fd, const struct iovec* iov, int iovcnt) { + if (fd == STDOUT_FILENO || fd == STDERR_FILENO) { + ssize_t total = 0; + std::string buffer; + for (int i = 0; i < iovcnt; ++i) { + if (iov[i].iov_base && iov[i].iov_len > 0) { + buffer.append(static_cast(iov[i].iov_base), + iov[i].iov_len); + total += iov[i].iov_len; + } + } + // SbLogRaw is line-oriented; split on newlines and drop the terminators. + size_t start = 0, pos; + while ((pos = buffer.find('\n', start)) != std::string::npos) { + buffer[pos] = '\0'; + if (pos > start) { + SbLogRaw(buffer.c_str() + start); + } + start = pos + 1; + } + if (start < buffer.size()) { + SbLogRaw(buffer.c_str() + start); + } + return total; + } + return __real_writev(fd, iov, iovcnt); +} + } // extern "C" diff --git a/starboard/build/config/starboard_target_type.gni b/starboard/build/config/starboard_target_type.gni index e8078edb0a0b..62cbb97c3fb2 100644 --- a/starboard/build/config/starboard_target_type.gni +++ b/starboard/build/config/starboard_target_type.gni @@ -62,6 +62,7 @@ template("starboard_platform_target") { "-Wl,--wrap=open", "-Wl,--wrap=openat", "-Wl,--wrap=stat", + "-Wl,--wrap=writev", ] } }