casaroli opened a new pull request, #21142:
URL: https://github.com/apache/nuttx/pull/21142

   ## Summary
   
   Some POSIX and BSD functions were only macros in the public headers, and 
libc had no symbol for them. A program that declares such a function itself, 
takes its address, or runs a configure link test for it, then does not compile 
or does not find it. This PR makes five of them real libc functions with the 
same behavior, one commit each:
   
   - `fdatasync()` (`<unistd.h>`): was `#define fdatasync(f) fsync(f)`. Now a 
function that calls `fsync()`. With the macro, a program that brings its own 
fallback `int fdatasync(int fd) { return fsync(fd); }` defined `fsync()` as a 
call to itself: an endless loop that replaced `fsync()` in the whole program.
   - `malloc_usable_size()` (`<malloc.h>`): was a macro of `malloc_size()`. Now 
a function that calls `malloc_size()`, and returns 0 for NULL.
   - `grantpt()` (`<stdlib.h>`, `CONFIG_PSEUDOTERM`): was a macro that gives 0. 
Now a function: NuttX creates the slave pseudoterminal with its owner and mode 
already, so `grantpt()` only checks that the descriptor is a pseudoterminal 
(`EBADF`, `ENOTTY` otherwise).
   - `execvp()`, `execlp()` and `execvpe()` (`<unistd.h>`, 
`CONFIG_LIBC_EXECFUNCS`): were macros of `execv()`, `execl()` and `execve()`. 
Now functions that do the same (with `CONFIG_LIBC_ENVPATH` all of them search 
the `PATH`). `execl()` and `execlp()` share their code.
   - `bcmp()`, `bcopy()` and `bzero()` (`<strings.h>`): were macros of 
`memcmp()`, `memmove()` and `memset()`. Now functions. GCC still expands calls 
with a known size inline (built-ins). With `CONFIG_FORTIFY_SOURCE`, `bcopy()` 
and `bzero()` get the same checks as `memmove()` and `memset()`.
   
   An earlier `bzero()` function was reverted in cb720024b66, because clang for 
macOS turns `memset(s, 0, n)` into a call of `bzero()`, so `bzero()` called 
itself in the simulator. `bzero()` now has `no_builtin("memset")` (from 
`nuttx/compiler.h`, as `memset()` has), so the call stays a call of `memset()`. 
The simulator on macOS with this PR boots and runs the tests (see Testing).
   
   The last commit updates `Documentation/reference/user/10_filesystem.rst`, 
which listed `bcmp()`, `bcopy()`, `bzero()`, `index()` and `rindex()` as 
macros. `Documentation/standards/posix.rst` already lists all of these 
functions as supported.
   
   ## Impact
   
   Nine new libc functions; the macros are gone. The same in flat, protected 
and kernel builds; nothing per architecture. The behavior of each call does not 
change, with one exception: `grantpt()` of a descriptor that is not a 
pseudoterminal now fails instead of returning 0.
   
   Possible break in source code (flat build too): a program that defines its 
own function-like macro of one of these names before it includes the header now 
gets a syntax error in the prototype, and `#ifdef execvp` (or another name) is 
false now. I found no such code in nuttx or nuttx-apps. The users in the two 
trees (crypto/, the crypto drivers, nshlib, system/sudo, sqlite, quickjs, 
libwebsockets, iperf, netlib, wapi and others) work unchanged. nuttx-apps' 
dropbear builds `scp.c` with `-Dexecvp=dropbear_scp_execvp`: before, 
`<unistd.h>` replaced that macro with its own `#define execvp execv` (a 
redefinition warning); now the prototype gets the port's name, so `scp.c` calls 
the port's function as intended.
   
   ## Testing
   
   Test programs, one per commit: `fdatasync.c` (takes `&fdatasync`; 
`fdatasync()` of a file on tmpfs and on v9fs; `fdatasync(-1)` gives `EBADF`), 
`mallocus.c` (declares `malloc_usable_size()` itself, as a link test does; size 
of a 100-byte block; NULL gives 0), `grantpt.c` (declares `grantpt()` itself; 
master pty gives 0; `/dev/null` and a closed descriptor give -1), `execp.c` 
(declares the three functions itself; a program that does not exist gives -1 
with `ENOENT`) and `bstring.c` (declares the three functions itself after 
`<strings.h>`; calls them through pointers, so the libc functions run). 
Compiled against the export of qemu-armv8a:knsh (kernel build, 
`CONFIG_PSEUDOTERM`, `CONFIG_FS_TMPFS`) and run under QEMU (HVF):
   
   | test | master 192ac6d3fbc | this PR |
   |---|---|---|
   | `fdatasync` | does not compile ('fdatasync' undeclared: a function-like 
macro) | address, tmpfs, v9fs, badfd PASS |
   | `mallocus` | does not link (undefined reference to `malloc_usable_size`) | 
link, size, null PASS |
   | `grantpt` | does not compile (`int grantpt(int);` expands to `int (0);`) | 
decl, master, notpty, badfd PASS |
   | `execp` | does not link (undefined references to `execvp`, `execlp`, 
`execvpe`) | link, noent PASS |
   | `bstring` | does not compile (the macros expand inside the declarations) | 
decl, bzero, bcopy, bcmp PASS |
   
   No test in nuttx-apps covers these functions; the programs are not part of 
this PR. Each commit alone on master gives the same PASS for its own test. 
ostest exits with status 0 on qemu-armv8a:knsh (kernel) and qemu-armv8a:nsh 
(flat), on master, on each commit alone and on this PR.
   
   Flat build: the five tests as builtin applications of qemu-armv8a:nsh: all 
PASS (fdatasync without the v9fs case), ostest 0.
   
   Simulator on macOS (arm64, clang 22), sim:nsh with the five tests as builtin 
applications. Apple clang 21 also compiles the old `bzero()` to a branch to 
itself.
   
   | | `bzero()` without `no_builtin("memset")` | this PR |
   |---|---|---|
   | sim:nsh | crashes (SIGSEGV) before the first output | boots; all five 
tests PASS |
   
   Builds, without new warnings: stm32f4discovery:nsh with `CONFIG_PSEUDOTERM` 
and `CONFIG_LIBC_EXECFUNCS` (flat, Cortex-M4, GCC 13.2), 
lm3s6965-ek:qemu-protected (protected, Cortex-M3), rv-virt:pnsh64 (protected, 
RISC-V, GCC 14.3), rv-virt:knsh64 (kernel, RISC-V), nucleo-h753zi:crypto 
(crypto/ and the STM32H7 crypto driver call `bcopy()` and `bzero()`), 
qemu-armv8a:nsh with `CONFIG_FORTIFY_SOURCE=2` (the new wrappers). The changed 
libc files and the tests also compile with clang 22 for Cortex-M4 with 
`-fno-builtin`, as the arm clang toolchain uses.
   
   `tools/checkpatch.sh -c -u -m -g` passes.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to