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

   ## Summary
   
   An alternative to #20570 for the environment in a kernel build, so that the 
two can be compared.
   
   In a kernel build the environment of a process is in its user heap, but 
`getenv()`, `setenv()` and the other functions were system calls, and `environ` 
was not a variable. This PR moves the environment functions to libc, as 
openvela does:
   
   - The first commit is openvela's e60e6de82f by guoshichao: the environment 
fields move from `task_group_s` to `task_info_s`, which is in user memory.
   - The second commit moves `getenv()`, `setenv()`, `putenv()`, `unsetenv()`, 
`clearenv()`, `secure_getenv()` and `get_environ_ptr()` to `libs/libc/environ`. 
They leave the system call table. The kernel keeps `env_dup()` for a new task, 
`env_release()`, `env_foreach()` for procfs, and `env_sanitize_secure()`.
   
   `environ` becomes an lvalue, so a program can assign it and change its 
entries, as POSIX allows. Programs do both: gnulib's `putenv()` replaces an 
entry in place, and GNU make assigns its own array, with strings on its stack. 
The code that freed the environment then freed strings that it did not 
allocate, and the heap asserted (inside the kernel, with #20570). libc now 
keeps the array that it allocated and a parallel array of the strings that it 
allocated, and compares them with `environ` before each change. It frees a 
string only while the string is still where libc put it; a string that a 
program put into the environment is never freed.
   
   ## Impact
   
   - All builds: the environment functions are libc functions, not system 
calls. Programs of a kernel build must be built again.
   - `environ` can be assigned in all builds.
   - `setenv(name, "", 1)` sets an empty value, as POSIX says. Before, it 
removed the variable.
   - In a kernel build `env_release()` does not free the environment of a user 
process: it is in the user heap, which goes away with the address environment.
   
   ## Testing
   
   A test program that assigns `environ` and changes its entries, built against 
the export package of `qemu-armv8a:knsh` and run in QEMU 11:
   
   ```
   nsh> envtest
   envtest: setenv A, B                        A=1 B=2 C=-
   envtest: environ[i] replaced in place       A=replaced-in-place B=2 C=-
   envtest: setenv A after the replacement     A=3 B=2 C=-
   envtest: unsetenv A                         A=- B=2 C=-
   envtest: environ = own array                A=- B=2 C=from-the-stack
   envtest: setenv B after the assignment      A=- B=4 C=from-the-stack
   envtest: clearenv                           A=- B=- C=-
   envtest: setenv A after clearenv            A=5 B=- C=-
   envtest: done
   ```
   
   `ostest` on `qemu-armv8a:knsh` (kernel build) and `qemu-armv8a:nsh` (flat 
build): the environment checks pass, and `ostest_main: Exiting with status 0`.
   
   Builds: `qemu-armv8a:knsh` (with `make export` and the apps `make import`), 
`rv-virt:knsh64`, `qemu-armv7a:knsh`, `sabre-6quad:netknsh`, 
`lm3s6965-ek:qemu-flat`, `lm3s6965-ek:qemu-protected`, `mps2-an500:nsh`, 
`qemu-armv8a:nsh`, `rv-virt:nsh64`, `esp32-devkitc:nsh`.
   
   `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