apps/system/system and popen: Adapt so that these can be used in the KERNEL build mode. In this case, simply replace task_spawn() with posix_spawn(). This depends on the existence of some environment where /bin/sh exists and can be used to execute one NSH command. For the case of system(), this change was more complete because it previously used task_create(). Now it uses either task_spawn() or posix_spawn(), depending upon the configuration.
This commit is contained in:
parent
08263367bc
commit
e3e911555a
@ -7,7 +7,7 @@ config SYSTEM_POPEN
|
||||
bool "popen()/pclose() Functions"
|
||||
default n
|
||||
select SCHED_WAITPID
|
||||
depends on NSH_LIBRARY && !BUILD_KERNEL
|
||||
depends on NSH_LIBRARY
|
||||
---help---
|
||||
Enable support for the popen() and pclose() interfaces.
|
||||
This will support execution of NSH commands from C code with
|
||||
@ -15,6 +15,15 @@ config SYSTEM_POPEN
|
||||
|
||||
if SYSTEM_POPEN
|
||||
|
||||
config SYSTEM_POPEN_SHPATH
|
||||
string "Path to shell command"
|
||||
default "/bin/sh"
|
||||
depends on BUILD_KERNEL
|
||||
---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
|
||||
NSH shell, executes one command (in argv[1]), then exits.
|
||||
|
||||
config SYSTEM_POPEN_STACKSIZE
|
||||
int "Shell stack size"
|
||||
default 2048 if !ARCH_SIM
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <sched.h>
|
||||
#include <spawn.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "nshlib/nshlib.h"
|
||||
|
||||
@ -188,7 +189,7 @@ FILE *popen(FAR const char *command, FAR const char *mode)
|
||||
goto errout_with_pipe;
|
||||
}
|
||||
|
||||
/* Initialize attributes for task_spawn(). */
|
||||
/* Initialize attributes for task_spawn() (or posix_spawn()). */
|
||||
|
||||
errcode = posix_spawnattr_init(&attr);
|
||||
if (errcode != 0)
|
||||
@ -202,7 +203,7 @@ FILE *popen(FAR const char *command, FAR const char *mode)
|
||||
goto errout_with_attrs;
|
||||
}
|
||||
|
||||
/* Set the correct task size and priority */
|
||||
/* Set the correct stack size and priority */
|
||||
|
||||
param.sched_priority = CONFIG_SYSTEM_POPEN_PRIORITY;
|
||||
errcode = posix_spawnattr_setschedparam(&attr, ¶m);
|
||||
@ -229,8 +230,8 @@ FILE *popen(FAR const char *command, FAR const char *mode)
|
||||
}
|
||||
|
||||
errcode = posix_spawnattr_setflags(&attr,
|
||||
POSIX_SPAWN_SETSCHEDPARAM |
|
||||
POSIX_SPAWN_SETSCHEDULER);
|
||||
POSIX_SPAWN_SETSCHEDPARAM |
|
||||
POSIX_SPAWN_SETSCHEDULER);
|
||||
if (errcode != 0)
|
||||
{
|
||||
goto errout_with_actions;
|
||||
@ -253,17 +254,25 @@ FILE *popen(FAR const char *command, FAR const char *mode)
|
||||
goto errout_with_actions;
|
||||
}
|
||||
|
||||
/* Call task_spawn(), re-directing stdin or stdout appropriately */
|
||||
/* Start the built-in */
|
||||
/* Call task_spawn() (or posix_spawn), re-directing stdin or stdout
|
||||
* appropriately.
|
||||
*/
|
||||
|
||||
argv[0] = (FAR char *)command;
|
||||
argv[1] = NULL;
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
errcode = posix_spawn(&container->shell, CONFIG_SYSTEM_POPEN_SHPATH,
|
||||
&file_actions, &attr, argv,
|
||||
(FAR char * const *)NULL);
|
||||
#else
|
||||
errcode = task_spawn(&container->shell, "popen", nsh_system, &file_actions,
|
||||
&attr, argv, (FAR char * const *)NULL);
|
||||
#endif
|
||||
|
||||
if (errcode != 0)
|
||||
{
|
||||
serr("ERROR: task_spawn failed: %d\n", result);
|
||||
serr("ERROR: Spawn failed: %d\n", result);
|
||||
goto errout_with_actions;
|
||||
}
|
||||
|
||||
@ -389,6 +398,6 @@ int pclose(FILE *stream)
|
||||
|
||||
return status;
|
||||
#else
|
||||
return EXIT_SUCCESS;
|
||||
return OK;
|
||||
#endif
|
||||
}
|
||||
|
@ -14,6 +14,15 @@ config SYSTEM_SYSTEM
|
||||
|
||||
if SYSTEM_SYSTEM
|
||||
|
||||
config SYSTEM_SYSTEM_SHPATH
|
||||
string "Path to shell command"
|
||||
default "/bin/sh"
|
||||
depends on BUILD_KERNEL
|
||||
---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
|
||||
NSH shell, executes one command (in argv[1]), then exits.
|
||||
|
||||
config SYSTEM_SYSTEM_STACKSIZE
|
||||
int "system stack size"
|
||||
default 2048 if !ARCH_SIM
|
||||
|
@ -42,7 +42,9 @@
|
||||
#include <sys/wait.h>
|
||||
#include <stdlib.h>
|
||||
#include <sched.h>
|
||||
#include <spawn.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "nshlib/nshlib.h"
|
||||
|
||||
@ -57,13 +59,13 @@
|
||||
* Use system to pass a command string to the NSH parser and wait for it
|
||||
* to finish executing.
|
||||
*
|
||||
* This is an experimental version with known incompatibilies:
|
||||
* This is an experimental version with known incompatibilities:
|
||||
*
|
||||
* 1. It is not a part of libc due to its close association with NSH. The
|
||||
* function is still prototyped in nuttx/include/stdlib.h, however.
|
||||
* 2. It cannot use /bin/sh since that program will not exist in most
|
||||
* embedded configurations. Rather, it will spawn a shell-specific
|
||||
* system command -- currenly only NSH.
|
||||
* system command -- currently only NSH.
|
||||
* 3. REVISIT: There may be some issues with returned values.
|
||||
* 4. Of course, only NSH commands will be supported so that still means
|
||||
* that many leveraged system() calls will still not be functional.
|
||||
@ -72,24 +74,90 @@
|
||||
|
||||
int system(FAR char *cmd)
|
||||
{
|
||||
FAR char *nshargv[2];
|
||||
int pid;
|
||||
FAR char *argv[2];
|
||||
struct sched_param param;
|
||||
posix_spawnattr_t attr;
|
||||
pid_t pid;
|
||||
int errcode;
|
||||
int rc;
|
||||
int ret;
|
||||
|
||||
/* REVISIT: If cmd is NULL, then system() should return a non-zero value to
|
||||
* indicate if the command processor is available or zero if it is not.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(cmd != NULL);
|
||||
|
||||
/* Spawn nsh_system() which will execute the command under the shell */
|
||||
/* Initialize attributes for task_spawn() (or posix_spawn()). */
|
||||
|
||||
nshargv[0] = cmd;
|
||||
nshargv[1] = NULL;
|
||||
|
||||
pid = task_create("system", CONFIG_SYSTEM_SYSTEM_PRIORITY,
|
||||
CONFIG_SYSTEM_SYSTEM_STACKSIZE, nsh_system,
|
||||
(FAR char * const *)nshargv);
|
||||
if (pid < 0)
|
||||
errcode = posix_spawnattr_init(&attr);
|
||||
if (errcode != 0)
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Set the correct stack size and priority */
|
||||
|
||||
param.sched_priority = CONFIG_SYSTEM_SYSTEM_PRIORITY;
|
||||
errcode = posix_spawnattr_setschedparam(&attr, ¶m);
|
||||
if (errcode != 0)
|
||||
{
|
||||
goto errout_with_attrs;
|
||||
}
|
||||
|
||||
errcode = task_spawnattr_setstacksize(&attr, CONFIG_SYSTEM_SYSTEM_STACKSIZE);
|
||||
if (errcode != 0)
|
||||
{
|
||||
goto errout_with_attrs;
|
||||
}
|
||||
|
||||
/* If robin robin scheduling is enabled, then set the scheduling policy
|
||||
* of the new task to SCHED_RR before it has a chance to run.
|
||||
*/
|
||||
|
||||
#if CONFIG_RR_INTERVAL > 0
|
||||
errcode = posix_spawnattr_setschedpolicy(&attr, SCHED_RR);
|
||||
if (errcode != 0)
|
||||
{
|
||||
goto errout_with_attrs;
|
||||
}
|
||||
|
||||
errcode = posix_spawnattr_setflags(&attr,
|
||||
POSIX_SPAWN_SETSCHEDPARAM |
|
||||
POSIX_SPAWN_SETSCHEDULER);
|
||||
if (errcode != 0)
|
||||
{
|
||||
goto errout_with_attrs;
|
||||
}
|
||||
|
||||
#else
|
||||
errcode = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDPARAM);
|
||||
if (errcode != 0)
|
||||
{
|
||||
goto errout_with_attrs;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Spawn nsh_system() which will execute the command under the shell. */
|
||||
|
||||
argv[0] = cmd;
|
||||
argv[1] = NULL;
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
errcode = posix_spawn(&pid, CONFIG_SYSTEM_OPEN_SHPATH, NULL, &attr,
|
||||
argv, (FAR char * const *)NULL);
|
||||
#else
|
||||
errcode = task_spawn(&pid, "popen", nsh_system, NULL, &attr,
|
||||
argv, (FAR char * const *)NULL);
|
||||
#endif
|
||||
|
||||
/* Release the attributes and check for an error from the spawn operation */
|
||||
|
||||
if (errcode != 0)
|
||||
{
|
||||
serr("ERROR: Spawn failed: %d\n", result);
|
||||
goto errout_with_attrs;
|
||||
}
|
||||
|
||||
/* Wait for the shell to return */
|
||||
@ -97,8 +165,18 @@ int system(FAR char *cmd)
|
||||
ret = waitpid(pid, &rc, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
/* The errno variable has already been set */
|
||||
|
||||
rc = ERROR;
|
||||
}
|
||||
|
||||
(void)posix_spawnattr_destroy(&attr);
|
||||
return rc;
|
||||
|
||||
errout_with_attrs:
|
||||
(void)posix_spawnattr_destroy(&attr);
|
||||
|
||||
errout:
|
||||
set_errno(errcode);
|
||||
return ERROR;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user