casaroli opened a new pull request, #20917: URL: https://github.com/apache/nuttx/pull/20917
## Summary POSIX requires `<unistd.h>` to declare `optarg`, `opterr`, `optind` and `optopt` as `extern` variables ([`<unistd.h>`, POSIX.1-2024](https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/unistd.h.html)). NuttX keeps these values per task, so `<unistd.h>` defines the names as macros (`(*(getoptargp()))` and so on). #20568 discussed a program that brings its own `getopt()` and its own variables of these names. The result: the macros stay the default and behave the same in flat, protected and kernel builds, and such a program defines `NUTTX_NO_GETOPT_MACROS` to switch them off. But with `NUTTX_NO_GETOPT_MACROS`, `<unistd.h>` does not declare the names at all. A file that includes only `<unistd.h>` and reads `optind`, while another file or library defines the variable, does not compile (`'optind' undeclared`). This PR declares the four names as the `extern` variables that POSIX specifies when `NUTTX_NO_GETOPT_MACROS` is defined. libc still defines no variables of these names. A program that defines `NUTTX_NO_GETOPT_MACROS` but does not bring its own `getopt()` and variables still fails to build, as #20568 requires: the link finds no `optarg`, `opterr`, `optind` or `optopt`. It does not run with wrong option values. Without `NUTTX_NO_GETOPT_MACROS` nothing changes. ## Impact Only programs that define `NUTTX_NO_GETOPT_MACROS` (no code in nuttx or nuttx-apps does). They now get the POSIX declarations. A program that defines one of these names with another type, or as `static`, now gets a compile error, as with other C libraries. A program that defines the macro but has no variables of these names now fails at link time, not at compile time. All build modes and architectures: the change is in a public header only. Documentation: the TLS page and the libc page say that the names are declared (separate commit). ## Testing Test programs, built against a `qemu-armv8a:knsh` export: - `getoptdecl.c`: defines `NUTTX_NO_GETOPT_MACROS`, reads the four variables in a function before the file defines them, and takes the address of `getopt()`. - `getoptnoimpl.c`: defines `NUTTX_NO_GETOPT_MACROS`, calls the `getopt()` of libc and reads `optarg` and `optind`, but defines no variables. | | master | this PR | |---|---|---| | `getoptdecl.c` on `qemu-armv8a:knsh` (QEMU with HVF) | does not compile: `'optind' undeclared`, the same for `opterr`, `optopt`, `optarg` | compiles, PASS | | `getoptnoimpl.c` | does not compile: `'optarg' undeclared`, `'optind' undeclared` | does not link: undefined references `optarg`, `optind` | | ostest, `qemu-armv8a:knsh` and `qemu-armv8a:nsh` | status 0 | status 0 | Build, each OK: `qemu-armv8a:nsh` (flat, arm64), `qemu-armv8a:knsh` (kernel, arm64), `rv-virt:knsh64` (kernel, rv64), `rv-virt:pnsh64` (protected, rv64), `lm3s6965-ek:qemu-protected` (protected, armv7-m). No new warnings. `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]
