Hello, I want to discuss a breaking change before I open the pull requests, as CONTRIBUTING.md 1.13 asks.
The problem NuttX added fopencookie() in 12.4.0 (#10602). The function comes from glibc. In glibc and in musl, the seek function of cookie_io_functions_t returns int: 0 on success, with the new offset stored in *offset, or -1 on failure: https://man7.org/linux/man-pages/man3/fopencookie.3.html In NuttX, cookie_seek_function_t returns off_t, and ftello() uses the return value as the position. So a seek function written for glibc or musl: - does not compile where off_t is not int: for example on 32-bit Arm (int32_t is long there), and with CONFIG_FS_LARGEFILE. GCC 13 warns (incompatible pointer type); GCC 14 and later stop with an error. libbsd's funopen.c is such a function. - compiles where off_t is int (arm64 without CONFIG_FS_LARGEFILE). But if it returns 0 on success, as the glibc documentation asks, ftell() returns 0 after fseek(), because the position comes from the return value. The proposal 1. nuttx: cookie_seek_function_t returns int. ftello() takes the position from *offset, and fseeko() fails when the result is negative. The seek functions of fmemopen() and open_memstream() return 0 (they already store the offset in *offset). 2. nuttx-apps: testing/libc/fopencookie returns 0 from its seek function. The two pull requests must merge together. What breaks - A seek function written for the NuttX type (an off_t result) gets the same warning or error as above, in the other direction. Quick fix: change the return type to int, store the new offset in *offset, and return 0 on success, or -1 with errno set on failure. - In nuttx and nuttx-apps, only testing/libc/fopencookie has such a function. The seek functions of fmemopen(), open_memstream() and popen() in libc change in the same commit. libtinycbor passes no seek function. I did not search the code that nuttx-apps downloads at build time. Alternatives 1. Keep the off_t type, and change only ftello() to take the position from *offset. Then the NuttX seek functions still work, but code written for glibc still does not compile where off_t is not int. A cast makes it compile, but then the program calls the function through the wrong type, which is undefined behaviour in C. So ported code still needs a NuttX-specific change. 2. A Kconfig option that selects the glibc type, off by default. Then the type of a public typedef depends on the configuration, and a library that uses fopencookie() works only in the configurations that set the option. Tests so far QEMU, qemu-armv8a:knsh (kernel build), with a test program that has a glibc-style seek function: on master, ftell() gives 0 after fseek(f, 6, SEEK_SET) and after fseek(f, 0, SEEK_END); with the change it gives 6 and 11. ftell() on fmemopen() and open_memstream() streams is right before and after. testing/libc/fopencookie passes on master and with the change. ostest passes on qemu-armv8a:knsh and qemu-armv8a:nsh. stm32f4discovery:nsh (flat) and lm3s6965-ek:qemu-protected (protected) build. Before a vote, I will add build and ostest logs from real hardware of more than one architecture, as CONTRIBUTING.md 1.14 requires. Question Do you agree with the change, or do you prefer one of the alternatives? Thank you, Marco Casaroli
