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]

Reply via email to