From a27f7af6b7d63dd286c160e96aa848b83c354f29 Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Wed, 25 Mar 2026 16:18:57 +0700 Subject: [PATCH] fix(esp_libc): picolibc: add workaround for setvbuf on _IONBF --- components/newlib/CMakeLists.txt | 4 +- .../newlib/src/picolibc/bufio_setvbuf.c | 39 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 components/newlib/src/picolibc/bufio_setvbuf.c diff --git a/components/newlib/CMakeLists.txt b/components/newlib/CMakeLists.txt index 658fa4c85f..a87d3a9e73 100644 --- a/components/newlib/CMakeLists.txt +++ b/components/newlib/CMakeLists.txt @@ -65,7 +65,9 @@ else() "src/picolibc/picolibc_init.c" "src/picolibc/rand.c" "src/picolibc/open_memstream.c" - "src/picolibc/errno.c") + "src/picolibc/errno.c" + "src/picolibc/bufio_setvbuf.c") # TODO IDF-15494: remove this and the following lines + list(APPEND EXTRA_LINK_FLAGS "-Wl,--wrap=__bufio_setvbuf") if(CONFIG_LIBC_PICOLIBC_NEWLIB_COMPATIBILITY) list(APPEND srcs "src/picolibc/getreent.c") endif() diff --git a/components/newlib/src/picolibc/bufio_setvbuf.c b/components/newlib/src/picolibc/bufio_setvbuf.c new file mode 100644 index 0000000000..5a92563133 --- /dev/null +++ b/components/newlib/src/picolibc/bufio_setvbuf.c @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include + +int __real___bufio_setvbuf(FILE *f, char *buf, int mode, size_t size); +int __wrap___bufio_setvbuf(FILE *f, char *buf, int mode, size_t size) +{ + // File lock is already acquired by the caller + int ret = -1; + bool workaround = false; + if (mode == _IONBF) { + workaround = true; + mode = _IOFBF; + size = 1; + buf = malloc(size); + if (buf == NULL) { + goto exit; + } + } + ret = __real___bufio_setvbuf(f, buf, mode, size); + if (workaround) { + struct __file_bufio *bf = (struct __file_bufio *)f; + + // Free buf if not applied + if (ret != 0 || bf->buf != buf) { + free(buf); + goto exit; + } + bf->bflags |= __BALL; + } + +exit: + return ret; +}