mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-01 20:29:00 +00:00
system/popen: support no-shell mode via posix_spawnp
When NSH_LIBRARY is not available, dpopen()/popen() can still execute commands by splitting the command string by whitespace and calling posix_spawnp() directly. Shell syntax (pipes, redirects, globbing) is not supported in this mode. Add CONFIG_SYSTEM_POPEN_MAXARGUMENTS (default 7) to control the argv array size for the no-shell path. Remove the hard dependency on NSH_LIBRARY from SYSTEM_POPEN so the feature can be used in minimal configurations without a shell. Signed-off-by: cuiziwei <cuiziwei@xiaomi.com>
This commit is contained in:
parent
0d35e2e0bb
commit
740fda9630
2 changed files with 78 additions and 8 deletions
|
|
@ -7,7 +7,7 @@ config SYSTEM_POPEN
|
|||
bool "popen()/pclose()/dpopen()/dpclose() Functions"
|
||||
default n
|
||||
select SCHED_WAITPID
|
||||
depends on NSH_LIBRARY && PIPES
|
||||
depends on PIPES
|
||||
---help---
|
||||
Enable support for the popen(), pclose(), dpopen(), and
|
||||
dpclose() interfaces.
|
||||
|
|
@ -20,16 +20,20 @@ config SYSTEM_POPEN
|
|||
popen()/pclose() are thin wrappers around dpopen()/dpclose()
|
||||
that additionally wrap the fd in a FILE stream.
|
||||
|
||||
Commands are executed through the NSH shell (sh -c command),
|
||||
supporting full shell syntax including pipes, redirects,
|
||||
and globbing.
|
||||
When NSH is available (NSH_LIBRARY), commands are executed
|
||||
through the shell (sh -c command), supporting full shell
|
||||
syntax including pipes, redirects, and globbing.
|
||||
|
||||
When NSH is not available, commands are executed directly
|
||||
via posix_spawnp(). The command string must be a simple
|
||||
"program arg1 arg2" form without shell syntax.
|
||||
|
||||
if SYSTEM_POPEN
|
||||
|
||||
config SYSTEM_POPEN_SHPATH
|
||||
string "Path to shell command"
|
||||
default "/bin/sh"
|
||||
depends on SYSTEM_NSH=m || BUILD_KERNEL
|
||||
depends on (SYSTEM_NSH=m || BUILD_KERNEL) && NSH_LIBRARY
|
||||
---help---
|
||||
This is the full path to the program in a mounted file system that
|
||||
implements the system() command. That is, a program that starts the
|
||||
|
|
@ -53,4 +57,17 @@ config SYSTEM_POPEN_PRIORITY
|
|||
---help---
|
||||
The priority of the shell.
|
||||
|
||||
config SYSTEM_POPEN_MAXARGUMENTS
|
||||
int "Maximum number of command arguments (no-shell mode)"
|
||||
default 7
|
||||
depends on !NSH_LIBRARY
|
||||
---help---
|
||||
When NSH is not available, dpopen()/popen() splits the command
|
||||
string by whitespace into an argv array. This sets the maximum
|
||||
number of arguments (excluding the program name and the
|
||||
terminating NULL).
|
||||
|
||||
This is analogous to CONFIG_NSH_MAXARGUMENTS but applies
|
||||
only to the no-shell path.
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <sys/wait.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sched.h>
|
||||
#include <spawn.h>
|
||||
#include <debug.h>
|
||||
|
|
@ -37,7 +38,17 @@
|
|||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include "nshlib/nshlib.h"
|
||||
#ifdef CONFIG_NSH_LIBRARY
|
||||
# include "nshlib/nshlib.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_NSH_LIBRARY
|
||||
# define DPOPEN_MAX_ARGV (CONFIG_SYSTEM_POPEN_MAXARGUMENTS + 1)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
@ -58,6 +69,10 @@
|
|||
* When NSH is available, commands are executed through the shell
|
||||
* (sh -c command), supporting full shell syntax.
|
||||
*
|
||||
* When NSH is not available, the command is split by whitespace and
|
||||
* executed directly via posix_spawnp(). Shell syntax (pipes, redirects,
|
||||
* globbing) is not supported in this mode.
|
||||
*
|
||||
* Input Parameters:
|
||||
* command - The command string to execute
|
||||
* oflag - O_RDONLY to read child stdout, O_WRONLY to write child stdin,
|
||||
|
|
@ -74,7 +89,14 @@ int dpopen(FAR const char *command, int oflag, FAR pid_t *pid)
|
|||
struct sched_param param;
|
||||
posix_spawnattr_t attr;
|
||||
posix_spawn_file_actions_t file_actions;
|
||||
#ifdef CONFIG_NSH_LIBRARY
|
||||
FAR char *argv[4];
|
||||
#else
|
||||
char cmdbuf[PATH_MAX];
|
||||
FAR char *argv[DPOPEN_MAX_ARGV];
|
||||
FAR char *saveptr;
|
||||
int argc = 0;
|
||||
#endif
|
||||
int fd[2];
|
||||
int childfd;
|
||||
int parentfd;
|
||||
|
|
@ -224,21 +246,52 @@ int dpopen(FAR const char *command, int oflag, FAR pid_t *pid)
|
|||
* appropriately.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NSH_LIBRARY
|
||||
/* Shell mode: execute command through sh -c */
|
||||
|
||||
argv[1] = "-c";
|
||||
argv[2] = (FAR char *)command;
|
||||
argv[3] = NULL;
|
||||
|
||||
#ifdef CONFIG_SYSTEM_POPEN_SHPATH
|
||||
# ifdef CONFIG_SYSTEM_POPEN_SHPATH
|
||||
argv[0] = CONFIG_SYSTEM_POPEN_SHPATH;
|
||||
errcode = posix_spawn(pid, argv[0], &file_actions,
|
||||
&attr, argv, NULL);
|
||||
#else
|
||||
# else
|
||||
*pid = task_spawn("dpopen", nsh_system, &file_actions,
|
||||
&attr, argv + 1, NULL);
|
||||
if (*pid < 0)
|
||||
{
|
||||
errcode = -*pid;
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
/* No-shell mode: split command and execute directly via posix_spawnp.
|
||||
* The command must be in "program arg1 arg2" form -- no shell syntax.
|
||||
*/
|
||||
|
||||
if (strlcpy(cmdbuf, command, sizeof(cmdbuf)) >= sizeof(cmdbuf))
|
||||
{
|
||||
errcode = ENAMETOOLONG;
|
||||
goto errout_with_actions;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
argv[argc] = strtok_r(argc ? NULL : cmdbuf, " \t", &saveptr);
|
||||
}
|
||||
while (argv[argc] != NULL && ++argc < DPOPEN_MAX_ARGV - 1);
|
||||
|
||||
argv[argc] = NULL;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
errcode = EINVAL;
|
||||
goto errout_with_actions;
|
||||
}
|
||||
|
||||
errcode = posix_spawnp(pid, argv[0], &file_actions,
|
||||
&attr, argv, NULL);
|
||||
#endif
|
||||
|
||||
if (errcode != 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue