Skip to content

[4/5] system/popen: Remove it and use the popen() of libc. - #3890

Open
casaroli wants to merge 1 commit into
apache:masterfrom
casaroli:popen-delete-apps
Open

casaroli wants to merge 1 commit into
apache:masterfrom
casaroli:popen-delete-apps

Conversation

@casaroli

@casaroli casaroli commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

libc has popen(), pclose(), dpopen() and dpclose() ([1/5] apache/nuttx#20778). The users of popen() in apps accept the libc copy ([2/5] #3877), and no nuttx configuration enables CONFIG_SYSTEM_POPEN any more ([3/5] apache/nuttx#20792).

This PR removes the code of system/popen. The fastboot shell command, the popen test, the popen example, dhcpd and gdbstub now depend only on the libc conditions: CONFIG_PIPES, CONFIG_LIBC_EXECFUNCS and CONFIG_SCHED_WAITPID. CONFIG_SYSTEM_POPEN stays as a deprecated option that only selects CONFIG_LIBC_EXECFUNCS and CONFIG_SCHED_WAITPID, so configurations that set it keep popen().

[5/5] apache/nuttx#20839 removes the CONFIG_SYSTEM_POPEN check from the libc build and moves the documentation page of system/popen to the libc documentation.

Impact

No nuttx configuration changes: the 15 configurations that used system/popen already use the libc copy. The libc copy has all the functions of the apps copy. The options CONFIG_SYSTEM_POPEN_SHPATH, CONFIG_SYSTEM_POPEN_STACKSIZE, CONFIG_SYSTEM_POPEN_PRIORITY and CONFIG_SYSTEM_POPEN_MAXARGUMENTS are removed: libc starts sh from PATH (or /bin/sh) with the posix_spawn() defaults, and has no limit on the number of arguments. popen() of libc accepts only the POSIX modes "r" and "w"; the apps copy also accepted "r+" and "w+". dpopen() with O_RDWR is still available.

A configuration out of the tree that sets CONFIG_SYSTEM_POPEN=y keeps building and gets the libc copy. CONFIG_SYSTEM_POPEN selected CONFIG_SCHED_WAITPID, so a defconfig from make savedefconfig does not contain CONFIG_SCHED_WAITPID; without the deprecated option, such a configuration would lose it, popen() would not be built, the popen users would be disabled without a message, and programs that call waitpid() (for example system/nxinit) would not compile. Tested with defconfigs from make savedefconfig of qemu-armv8a:nsh and :netnsh with CONFIG_SYSTEM_POPEN=y, with and without CONFIG_SYSTEM_SYSTEM: all build with the libc copy and lose no option.

Testing

Built with [5/5], all with CONFIG_SYSTEM_POPEN gone and the libc lib_popen.o and lib_dpopen.o built. After make olddefconfig, no option of the defconfig was lost: CONFIG_SYSTEM_FASTBOOTD_SHELL=y and CONFIG_EXAMPLES_POPEN=y stay set.

Configuration Result
qemu-armv8a:fastboot builds, CONFIG_SYSTEM_FASTBOOTD_SHELL=y
sabre-6quad:citest, rv-virt:citest, rv-virt:citest64 build, CONFIG_EXAMPLES_POPEN=y
lx_cpu:nsh builds
esp32s3-devkit:fastboot, :fastboot_tcp, :fastboot_usb, lckfb-szpi-esp32s3:fastboot, :fastboot_tcp, :fastboot_usb build, CONFIG_SYSTEM_FASTBOOTD_SHELL=y
sim:citest, sim:quickjs (x86_64 Linux in Docker) build, CONFIG_EXAMPLES_POPEN=y in sim:citest
qemu-intel64:citest_smp (x86_64 Linux in Docker) builds, CONFIG_EXAMPLES_POPEN=y

sim:sqlite was not built: the build host has no tclsh, which the SQLite build needs.

Runtime on qemu-armv8a:knsh (kernel build) and qemu-armv8a:nsh (flat build), QEMU with HVF, with CONFIG_TESTING_POPEN, CONFIG_EXAMPLES_POPEN and CONFIG_SCHED_CHILD_STATUS: popen_test passes all 8 tests (=== Results: 0 failed ===), incl. test 8 (pclose() returns the failure status of the command). popen (the example) reads the output of help to End of data and exits with 0.

tools/checkpatch.sh -c -u -m -g passes.

Comment thread system/popen/Kconfig Outdated
libc has popen(), pclose(), dpopen() and dpclose() when CONFIG_PIPES,
CONFIG_LIBC_EXECFUNCS and CONFIG_SCHED_WAITPID are set, and no
configuration in nuttx enables CONFIG_SYSTEM_POPEN any more.

Remove the code of system/popen.  The fastboot shell command, the popen
test, the popen example, dhcpd and gdbstub now depend on the libc
conditions only.

Remove CONFIG_SYSTEM_POPEN too.  It selected CONFIG_LIBC_EXECFUNCS and
CONFIG_SCHED_WAITPID, so a configuration that sets only it must now set
these two options in its place.

The options of the old copy for the priority, the stack size, the shell
path and the number of arguments have no replacement: popen() uses the
posix_spawn() defaults.  popen() does not accept the modes "r+" and "w+";
dpopen() with O_RDWR gives a bidirectional pipe.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <[email protected]>
@casaroli casaroli closed this Oct 22, 2026
@casaroli casaroli reopened this Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants