casaroli opened a new pull request, #20570: URL: https://github.com/apache/nuttx/pull/20570
## Summary POSIX specifies `extern char **environ;`, and programs assign it, for example `environ = some_array;` before they run another program. NuttX defines `environ` as a macro for `get_environ_ptr()`, so those programs do not compile: `error: lvalue required as left operand of assignment`. Commit 1, kernel builds: in the user space of a kernel build every process has its own copy of the C library data, so `environ` is now a real variable. - libc defines it. crt0 sets it to the environment and registers its address in the new `ar_environ` field of the process's reserved data area. - The kernel keeps owning the environment. `getenv()`, `setenv()`, `unsetenv()`, `clearenv()` and `get_environ_ptr()` first take over an array that the program assigned to `environ` (`env_sync_in()`), and copy it before the old environment is freed, because its strings often point into the old one. After a change they point `environ` at the new environment (`env_sync_out()`). `exec` and `posix_spawn` see the program's array through the same path. - A program built before this change is not affected: its reserved area holds `NULL`. Commit 2, flat and protected builds: all tasks share the C library data, so `environ` cannot be one variable. The new option `CONFIG_LIBC_ENVIRON_ASSIGNABLE` (default n) makes `environ` name a per-task-group location: `#define environ (*get_environ_location())`, the new `ta_environ` field of the group's `task_info_s`. That is an lvalue, so `environ = array;` compiles. The kernel uses the same `env_sync_in()` and `env_sync_out()`. ## Impact Kernel builds: `environ` is a variable in user space; the kernel code above runs on each environment call. Flat and protected builds: no change unless `CONFIG_LIBC_ENVIRON_ASSIGNABLE=y`. Size (text + data), flat builds with the option off: no change on `lm3s6965-ek:qemu-flat` (262000) and `mps2-an500:nsh` (365031). With the option on: +360 bytes on `mps2-an500:nsh`, +188 bytes on `lm3s6965-ek:qemu-protected`. Not supported: changing one entry of the kernel's array in place (`environ[i] = "X=1"`). With the option, a program's own `extern char **environ;` compiles with a `-Wstrict-prototypes` warning, as for `errno`. ## Testing QEMU 11. Test programs built outside the tree against the export package for `knsh`, and built into the image in place of `examples/hello` for `nsh`. `qemu-armv8a:knsh`: a program assigns `environ`, calls `setenv()`, runs itself as a child with `posix_spawnp(..., environ)`, then calls `clearenv()`. Before: ``` envassign.c:24:11: error: lvalue required as left operand of assignment ``` After: ``` envassign: getenv(FOO) = bar envassign: [FOO=bar] envassign: [PATH=/system/bin] envassign: [X=1] envassign: child FOO=bar X=1 envassign: after clearenv environ 0 ``` `qemu-armv8a:nsh` (flat) with `CONFIG_LIBC_ENVIRON_ASSIGNABLE=y`: the same steps, with a child task from `task_create()`. Without the option the program does not compile (lvalue error), as before. ``` flatenv: getenv(FOO) = bar flatenv: [FOO=bar] flatenv: [PATH=/bin] flatenv: [X=1] flatenv: child FOO=bar X=1 flatenv: child [FOO=bar] flatenv: child [PATH=/bin] flatenv: child [X=1] flatenv: after clearenv environ 0 getenv(FOO) (null) ``` Kernel builds with `-Wno-cpp -Werror`, each followed by `make export` and the apps `make import`: `qemu-armv8a:knsh`, `imx93-evk:knsh`, `qemu-armv7a:knsh`, `sabre-6quad:netknsh`, `sama5d4-ek:knsh`, `rv-virt:knsh`, `rv-virt:knsh64`, `rv-virt:ksmp64`, `rv-virt:knsh_paging`, `rv-virt:knetnsh64`, `rv-virt:kfb64`, `icicle:knsh`, `canmv230:knsh`, `esp32s3-devkit:kernel_n8r2`. Flat and protected builds with `-Wno-cpp -Werror`, option off and on: `lm3s6965-ek:qemu-flat` (on: overflows flash by 24 bytes; the board has no room left), `mps2-an500:nsh`, `lm3s6965-ek:qemu-protected`. `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]
