NSH will now run files from the file system; Add logic to unload and clean-up after running a task from a file system; Extensions to builtin apps from Mike Smith
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5529 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
d8d9cc8a96
commit
68453d683c
|
@ -485,3 +485,6 @@
|
|||
argument is now optional. Many files systems do not need
|
||||
a source and it is really stupid to have to enter a bogus
|
||||
source parameter.
|
||||
* apps/nshlib/nsh_fileapp.c: Add the ability to execute a file
|
||||
from a file system using posix_spawn().
|
||||
* apps/builtin/: Extensions from Mike Smith.
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/****************************************************************************
|
||||
* apps/builtin/builtin_list.c
|
||||
*
|
||||
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Authors: Uros Platise <uros.platise@isotel.eu>
|
||||
* Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <nuttx/binfmt/builtin.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#include "builtin_proto.h"
|
||||
|
||||
const struct builtin_s g_builtins[] =
|
||||
{
|
||||
# include "builtin_list.h"
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
const int g_builtin_count = sizeof(g_builtins) / sizeof(g_builtins[0]);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -46,6 +46,12 @@
|
|||
#include <errno.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#if defined(CONFIG_FS_BINFS) && (CONFIG_BUILTIN)
|
||||
#include <nuttx/binfmt/builtin.h>
|
||||
#endif
|
||||
#if defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_EXECFUNCS_SYMTAB)
|
||||
#include <nuttx/binfmt/symtab.h>
|
||||
#endif
|
||||
|
||||
#include <apps/nsh.h>
|
||||
|
||||
|
@ -75,6 +81,21 @@
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* If posix_spawn() is enabled as required for CONFIG_NSH_FILE_APPS, then
|
||||
* a symbol table is needed by the internals of posix_spawn(). The symbol
|
||||
* table is needed to support ELF and NXFLAT binaries to dynamically link to
|
||||
* the base code. However, if only the BINFS file system is supported, then
|
||||
* no Makefile is needed.
|
||||
*
|
||||
* This is a kludge to plug the missing file system in the case where BINFS
|
||||
* is used. REVISIT: This will, of course, be in the way if you want to
|
||||
* support ELF or NXFLAT binaries!
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_EXECFUNCS_SYMTAB)
|
||||
const struct symtab_s CONFIG_EXECFUNCS_SYMTAB[1];
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -98,6 +119,23 @@ int nsh_main(int argc, char *argv[])
|
|||
up_cxxinitialize();
|
||||
#endif
|
||||
|
||||
/* Make sure that we are using our symbol take */
|
||||
|
||||
#if defined(CONFIG_LIBC_EXECFUNCS) && defined(CONFIG_EXECFUNCS_SYMTAB)
|
||||
exec_setsymtab(CONFIG_EXECFUNCS_SYMTAB, 0);
|
||||
#endif
|
||||
|
||||
/* Register the BINFS file system */
|
||||
|
||||
#if defined(CONFIG_FS_BINFS) && (CONFIG_BUILTIN)
|
||||
ret = builtin_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: builtin_initialize failed: %d\n", ret);
|
||||
exitval = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize the NSH library */
|
||||
|
||||
nsh_initialize();
|
||||
|
|
|
@ -14,7 +14,7 @@ config NSH_LIBRARY
|
|||
if NSH_LIBRARY
|
||||
config NSH_BUILTIN_APPS
|
||||
bool "Enable built-in applications"
|
||||
default y
|
||||
default n
|
||||
depends on BUILTIN
|
||||
---help---
|
||||
Support external registered, "built-in" applications that can be
|
||||
|
@ -22,6 +22,15 @@ config NSH_BUILTIN_APPS
|
|||
more information). This options requires support for builtin
|
||||
applications (BUILTIN).
|
||||
|
||||
config NSH_FILE_APPS
|
||||
bool "Enable execution of program files"
|
||||
default n
|
||||
depends on LIBC_EXECFUNCS
|
||||
---help---
|
||||
Support execution of program files residing within a file
|
||||
system. This options requires support for the posix_spawn()
|
||||
interface (LIBC_EXECFUNCS).
|
||||
|
||||
menu "Disable Individual commands"
|
||||
|
||||
config NSH_DISABLE_BASE64DEC
|
||||
|
|
|
@ -47,6 +47,10 @@ ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
|||
CSRCS += nsh_builtin.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NSH_FILE_APPS),y)
|
||||
CSRCS += nsh_fileapps.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NSH_ROMFSETC),y)
|
||||
CSRCS += nsh_romfsetc.c
|
||||
endif
|
||||
|
|
|
@ -495,6 +495,11 @@ int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
|||
FAR char **argv, FAR const char *redirfile, int oflags);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NSH_FILE_APPS
|
||||
int nsh_fileapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
FAR char **argv, FAR const char *redirfile, int oflags);
|
||||
#endif
|
||||
|
||||
/* Working directory support */
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -129,20 +130,34 @@ int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
|||
ret = exec_builtin(cmd, (FAR const char **)argv, redirfile, oflags);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* The application was successfully started (but still blocked because
|
||||
* the scheduler is locked). If the application was not backgrounded,
|
||||
* then we need to wait here for the application to exit. These really
|
||||
* only works works with the following options:
|
||||
/* The application was successfully started with pre-emption disabled.
|
||||
* In the simplest cases, the application will not have run because the
|
||||
* the scheduler is locked. but in the case were I/O redirected, a
|
||||
* proxy task ran and, as result, so may have the application.
|
||||
*
|
||||
* If the application did not run and if the application was not
|
||||
* backgrounded, then we need to wait here for the application to
|
||||
* exit. This only works works with the following options:
|
||||
*
|
||||
* - CONFIG_NSH_DISABLEBG - Do not run commands in background
|
||||
* - CONFIG_SCHED_WAITPID - Required to run external commands in
|
||||
* foreground
|
||||
*
|
||||
* These concepts do not apply cleanly to the external applications.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SCHED_WAITPID
|
||||
|
||||
/* Check if the application is still running */
|
||||
|
||||
if (kill(ret, 0) < 0)
|
||||
{
|
||||
/* It is not running. In this case, we have no idea if the
|
||||
* application ran successfully or not. Let's assume that is
|
||||
* did.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* CONFIG_SCHED_WAITPID is selected, so we may run the command in
|
||||
* foreground unless we were specifically requested to run the command
|
||||
* in background (and running commands in background is enabled).
|
||||
|
|
|
@ -0,0 +1,298 @@
|
|||
/****************************************************************************
|
||||
* apps/nshlib/nsh_fileapps.c
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifdef CONFIG_SCHED_WAITPID
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <signal.h>
|
||||
#include <spawn.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nsh.h"
|
||||
#include "nsh_console.h"
|
||||
|
||||
#ifdef CONFIG_NSH_FILE_APPS
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_fileapp
|
||||
*
|
||||
* Description:
|
||||
* Attempt to execute the application task whose name is 'cmd'
|
||||
*
|
||||
* Returned Value:
|
||||
* <0 If exec_builtin() fails, then the negated errno value
|
||||
* is returned.
|
||||
* -1 (ERROR) if the application task corresponding to 'cmd' could not
|
||||
* be started (possibly because it doesn not exist).
|
||||
* 0 (OK) if the application task corresponding to 'cmd' was
|
||||
* and successfully started. If CONFIG_SCHED_WAITPID is
|
||||
* defined, this return value also indicates that the
|
||||
* application returned successful status (EXIT_SUCCESS)
|
||||
* 1 If CONFIG_SCHED_WAITPID is defined, then this return value
|
||||
* indicates that the application task was spawned successfully
|
||||
* but returned failure exit status.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nsh_fileapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
|
||||
FAR char **argv, FAR const char *redirfile, int oflags)
|
||||
{
|
||||
posix_spawn_file_actions_t file_actions;
|
||||
posix_spawnattr_t attr;
|
||||
pid_t pid;
|
||||
int ret;
|
||||
|
||||
/* Initialize the attributes file actions structure */
|
||||
|
||||
ret = posix_spawn_file_actions_init(&file_actions);
|
||||
if (ret != 0)
|
||||
{
|
||||
/* posix_spawn_file_actions_init returns a positive errno value on
|
||||
* failure.
|
||||
*/
|
||||
|
||||
nsh_output(vtbl, g_fmtcmdfailed, cmd, "posix_spawn_file_actions_init",
|
||||
NSH_ERRNO_OF(ret));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
ret = posix_spawnattr_init(&attr);
|
||||
if (ret != 0)
|
||||
{
|
||||
/* posix_spawnattr_init returns a positive errno value on failure. */
|
||||
|
||||
nsh_output(vtbl, g_fmtcmdfailed, cmd, "posix_spawnattr_init",
|
||||
NSH_ERRNO);
|
||||
goto errout_with_actions;
|
||||
}
|
||||
|
||||
/* Handle re-direction of output */
|
||||
|
||||
if (redirfile)
|
||||
{
|
||||
ret = posix_spawn_file_actions_addopen(&file_actions, 1, redirfile,
|
||||
oflags, 0644);
|
||||
if (ret != 0)
|
||||
{
|
||||
/* posix_spawn_file_actions_addopen returns a positive errno
|
||||
* value on failure.
|
||||
*/
|
||||
|
||||
nsh_output(vtbl, g_fmtcmdfailed, cmd,
|
||||
"posix_spawn_file_actions_addopen",
|
||||
NSH_ERRNO);
|
||||
goto errout_with_attrs;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock the scheduler to prevent the application from running until the
|
||||
* waitpid() has been called.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Execute the program. posix_spawnp returns a positive errno value on
|
||||
* failure.
|
||||
*/
|
||||
|
||||
ret = posix_spawnp(&pid, cmd, &file_actions, &attr, &argv[1], NULL);
|
||||
if (ret == OK)
|
||||
{
|
||||
/* The application was successfully started with pre-emption disabled.
|
||||
* In the simplest cases, the application will not have run because the
|
||||
* the scheduler is locked. but in the case were I/O redirected, a
|
||||
* proxy task ran and, as result, so may have the application.
|
||||
*
|
||||
* If the application did not run and if the application was not
|
||||
* backgrounded, then we need to wait here for the application to
|
||||
* exit. This only works works with the following options:
|
||||
*
|
||||
* - CONFIG_NSH_DISABLEBG - Do not run commands in background
|
||||
* - CONFIG_SCHED_WAITPID - Required to run external commands in
|
||||
* foreground
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SCHED_WAITPID
|
||||
/* Check if the application is still running */
|
||||
|
||||
if (kill(ret, 0) < 0)
|
||||
{
|
||||
/* It is not running. In this case, we have no idea if the
|
||||
* application ran successfully or not. Let's assume that is
|
||||
* did.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* CONFIG_SCHED_WAITPID is selected, so we may run the command in
|
||||
* foreground unless we were specifically requested to run the command
|
||||
* in background (and running commands in background is enabled).
|
||||
*/
|
||||
|
||||
# ifndef CONFIG_NSH_DISABLEBG
|
||||
if (vtbl->np.np_bg == false)
|
||||
# endif /* CONFIG_NSH_DISABLEBG */
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
/* Wait for the application to exit. Since we have locked the
|
||||
* scheduler above, we know that the application has not yet
|
||||
* started and there is no possibility that it has already exited.
|
||||
* The scheduler will be unlocked while waitpid is waiting and the
|
||||
* application will be able to run.
|
||||
*/
|
||||
|
||||
ret = waitpid(pid, &rc, 0);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* We can't return the exact status (nsh has nowhere to put it)
|
||||
* so just pass back zero/nonzero in a fashion that doesn't look
|
||||
* like an error.
|
||||
*/
|
||||
|
||||
ret = (rc == 0) ? OK : 1;
|
||||
|
||||
/* TODO: Set the environment variable '?' to a string corresponding
|
||||
* to WEXITSTATUS(rc) so that $? will expand to the exit status of
|
||||
* the most recently executed task.
|
||||
*/
|
||||
}
|
||||
}
|
||||
# ifndef CONFIG_NSH_DISABLEBG
|
||||
else
|
||||
# endif /* CONFIG_NSH_DISABLEBG */
|
||||
#endif /* CONFIG_SCHED_WAITPID */
|
||||
|
||||
/* We get here if either:
|
||||
*
|
||||
* - CONFIG_SCHED_WAITPID is not selected meaning that all commands
|
||||
* have to be run in background, or
|
||||
* - CONFIG_SCHED_WAITPID and CONFIG_NSH_DISABLEBG are both selected, but the
|
||||
* user requested to run the command in background.
|
||||
*
|
||||
* NOTE that the case of a) CONFIG_SCHED_WAITPID is not selected and
|
||||
* b) CONFIG_NSH_DISABLEBG selected cannot be supported. In that event, all
|
||||
* commands will have to run in background. The waitpid() API must be
|
||||
* available to support running the command in foreground.
|
||||
*/
|
||||
|
||||
#if !defined(CONFIG_SCHED_WAITPID) || !defined(CONFIG_NSH_DISABLEBG)
|
||||
{
|
||||
struct sched_param param;
|
||||
sched_getparam(ret, ¶m);
|
||||
nsh_output(vtbl, "%s [%d:%d]\n", cmd, ret, param.sched_priority);
|
||||
|
||||
/* Backgrounded commands always 'succeed' as long as we can start
|
||||
* them.
|
||||
*/
|
||||
|
||||
ret = OK;
|
||||
}
|
||||
#endif /* !CONFIG_SCHED_WAITPID || !CONFIG_NSH_DISABLEBG */
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
|
||||
/* Free attibutes and file actions. Ignoring return values in the case
|
||||
* of an error.
|
||||
*/
|
||||
|
||||
errout_with_actions:
|
||||
(void)posix_spawn_file_actions_destroy(&file_actions);
|
||||
|
||||
errout_with_attrs:
|
||||
(void)posix_spawnattr_destroy(&attr);
|
||||
|
||||
errout:
|
||||
/* Most posix_spawn interfaces return a positive errno value on failure
|
||||
* and do not set the errno variable.
|
||||
*/
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
/* Set the errno value and return -1 */
|
||||
|
||||
set_errno(ret);
|
||||
ret = ERROR;
|
||||
}
|
||||
else if (ret < 0)
|
||||
{
|
||||
/* Return -1 on failure. errno should have been set. */
|
||||
|
||||
ret = ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NSH_FILE_APPS */
|
|
@ -61,6 +61,7 @@
|
|||
#ifdef CONFIG_NSH_BUILTIN_APPS
|
||||
# include <nuttx/binfmt/builtin.h>
|
||||
#endif
|
||||
|
||||
#include <apps/nsh.h>
|
||||
|
||||
#include "nsh.h"
|
||||
|
@ -1398,6 +1399,40 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
|
|||
nsh_output(vtbl, g_fmttoomanyargs, cmd);
|
||||
}
|
||||
|
||||
/* Does this command correspond to an application filename?
|
||||
* nsh_fileapp() returns:
|
||||
*
|
||||
* -1 (ERROR) if the application task corresponding to 'argv[0]' could not
|
||||
* be started (possibly because it doesn not exist).
|
||||
* 0 (OK) if the application task corresponding to 'argv[0]' was
|
||||
* and successfully started. If CONFIG_SCHED_WAITPID is
|
||||
* defined, this return value also indicates that the
|
||||
* application returned successful status (EXIT_SUCCESS)
|
||||
* 1 If CONFIG_SCHED_WAITPID is defined, then this return value
|
||||
* indicates that the application task was spawned successfully
|
||||
* but returned failure exit status.
|
||||
*
|
||||
* Note the priority if not effected by nice-ness.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NSH_FILE_APPS
|
||||
ret = nsh_fileapp(vtbl, argv[0], argv, redirfile, oflags);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* nsh_fileapp() returned 0 or 1. This means that the builtin
|
||||
* command was successfully started (although it may not have ran
|
||||
* successfully). So certainly it is not an NSH command.
|
||||
*/
|
||||
|
||||
return nsh_saveresult(vtbl, ret != OK);
|
||||
}
|
||||
|
||||
/* No, not a built in command (or, at least, we were unable to start a
|
||||
* builtin command of that name). Treat it like an NSH command.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/* Does this command correspond to a builtin command?
|
||||
* nsh_builtin() returns:
|
||||
*
|
||||
|
@ -1414,7 +1449,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
|
|||
* Note the priority if not effected by nice-ness.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NSH_BUILTIN_APPS
|
||||
#if defined(CONFIG_NSH_BUILTIN_APPS) && (!defined(CONFIG_NSH_FILE_APPS) || !defined(CONFIG_FS_BINFS))
|
||||
ret = nsh_builtin(vtbl, argv[0], argv, redirfile, oflags);
|
||||
if (ret >= 0)
|
||||
{
|
||||
|
|
|
@ -3967,4 +3967,8 @@
|
|||
file system.
|
||||
* configs/sim/nsh: Convert to use kconfig-frontends configuration
|
||||
tool.
|
||||
* binfmt/binfmt_schedunload.c: Add logic based on SIGCHLD to
|
||||
automatically unload and clean-up after running a task that
|
||||
was loaded into memory.
|
||||
* binfmt/libbuiltin: Extensions from Mike Smith
|
||||
|
||||
|
|
|
@ -183,9 +183,43 @@
|
|||
# define STM32_NRNG 0 /* No random number generator (RNG) */
|
||||
# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */
|
||||
|
||||
/* STM32 F103 Medium Density Family *************************************************/
|
||||
/* STM32F103RB is in the Medium-density performance line and is provided in 64 pin
|
||||
* packages with 128K Flash, USB, CAN, 7 timers, 2 ADCs, 9 com. interfaces
|
||||
*/
|
||||
|
||||
#elif defined(CONFIG_ARCH_CHIP_STM32F103RBT6)
|
||||
# define CONFIG_STM32_STM32F10XX 1 /* STM32F10xxx family */
|
||||
# undef CONFIG_STM32_LOWDENSITY /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 16/32 Kbytes */
|
||||
# define CONFIG_STM32_MEDIUMDENSITY 1 /* STM32F100x, STM32F101x, STM32F102x and STM32F103x w/ 64/128 Kbytes */
|
||||
# undef CONFIG_STM32_HIGHDENSITY /* STM32F100x, STM32F101x, and STM32F103x w/ 256/512 Kbytes */
|
||||
# undef CONFIG_STM32_VALUELINE /* STM32F100x */
|
||||
# undef CONFIG_STM32_CONNECTIVITYLINE /* STM32F105x and STM32F107x */
|
||||
# undef CONFIG_STM32_STM32F20XX /* STM32F205x and STM32F207x */
|
||||
# undef CONFIG_STM32_STM32F40XX /* STM32F405xx and STM32407xx families */
|
||||
# define STM32_NFSMC 0 /* FSMC */
|
||||
# define STM32_NATIM 1 /* One advanced timer TIM1 */
|
||||
# define STM32_NGTIM 3 /* General timers TIM2,3,4 */
|
||||
# define STM32_NBTIM 0 /* Two basic timers TIM6 and TIM7 */
|
||||
# define STM32_NDMA 1 /* DMA1 */
|
||||
# define STM32_NSPI 2 /* SPI1-2 */
|
||||
# define STM32_NI2S 0 /* No I2S (?) */
|
||||
# define STM32_NUSART 3 /* USART1-3 */
|
||||
# define STM32_NI2C 2 /* I2C1-2 */
|
||||
# define STM32_NCAN 1 /* bxCAN1 */
|
||||
# define STM32_NSDIO 0 /* No SDIO */
|
||||
# define STM32_NUSBOTG 0 /* No USB OTG FS/HS */
|
||||
# define STM32_NGPIO 51 /* GPIOA-E */
|
||||
# define STM32_NADC 2 /* ADC1-2 */
|
||||
# define STM32_NDAC 0 /* No DAC */
|
||||
# define STM32_NCRC 1 /* CRC */
|
||||
# define STM32_NTHERNET 0 /* No ethernet */
|
||||
# define STM32_NRNG 0 /* No random number generator (RNG) */
|
||||
# define STM32_NDCMI 0 /* No digital camera interface (DCMI) */
|
||||
|
||||
/* STM32 F103 High Density Family ***************************************************/
|
||||
/* STM32F103RC, STM32F103RD, and STM32F103RE are all provided in 64 pin packages and differ
|
||||
* only in the available FLASH and SRAM.
|
||||
/* STM32F103RC, STM32F103RD, and STM32F103RE are all provided in 64 pin packages and
|
||||
* differ only in the available FLASH and SRAM.
|
||||
*/
|
||||
|
||||
#elif defined(CONFIG_ARCH_CHIP_STM32F103RET6)
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/binfmt.h>
|
||||
|
||||
#include "binfmt_internal.h"
|
||||
|
@ -97,6 +98,7 @@ int exec(FAR const char *filename, FAR const char **argv,
|
|||
#ifdef CONFIG_SCHED_ONEXIT
|
||||
FAR struct binary_s *bin;
|
||||
int errorcode;
|
||||
int pid;
|
||||
int ret;
|
||||
|
||||
/* Allocate the load information */
|
||||
|
@ -131,8 +133,8 @@ int exec(FAR const char *filename, FAR const char **argv,
|
|||
|
||||
/* Then start the module */
|
||||
|
||||
ret = exec_module(bin);
|
||||
if (ret < 0)
|
||||
pid = exec_module(bin);
|
||||
if (pid < 0)
|
||||
{
|
||||
bdbg("ERROR: Failed to execute program '%s'\n", filename);
|
||||
sched_unlock();
|
||||
|
@ -145,14 +147,14 @@ int exec(FAR const char *filename, FAR const char **argv,
|
|||
* when the task exists.
|
||||
*/
|
||||
|
||||
ret = schedul_unload(ret, bin);
|
||||
ret = schedule_unload(pid, bin);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: Failed to schedul unload '%s'\n", filename);
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
return ret;
|
||||
return pid;
|
||||
#else
|
||||
struct binary_s bin;
|
||||
int ret;
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
static int load_default_priority(FAR struct binary_s *bin)
|
||||
{
|
||||
struct sched_param param;
|
||||
int ret;
|
||||
|
||||
/* Get the priority of this thread */
|
||||
|
||||
|
@ -97,6 +98,7 @@ static int load_default_priority(FAR struct binary_s *bin)
|
|||
/* Save that as the priority of child thread */
|
||||
|
||||
bin->priority = param.sched_priority;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -180,7 +182,7 @@ int load_module(FAR struct binary_s *bin)
|
|||
{
|
||||
/* Set the default priority of the new program. */
|
||||
|
||||
ret = load_default_priority(bin)
|
||||
ret = load_default_priority(bin);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* The errno is already set in this case */
|
||||
|
|
|
@ -0,0 +1,333 @@
|
|||
/****************************************************************************
|
||||
* binfmt/binfmt_schedunload.c
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sched.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/binfmt/binfmt.h>
|
||||
|
||||
#include "binfmt_internal.h"
|
||||
|
||||
#if !defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_SCHED_HAVE_PARENT)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct binary_s *g_unloadhead;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: unload_list_add
|
||||
*
|
||||
* Description:
|
||||
* If CONFIG_SCHED_HAVE_PARENT is defined then schedul_unload() will
|
||||
* manage instances of struct binary_s allocated with kmalloc. It
|
||||
* will keep the binary data in a link list and when SIGCHLD is received
|
||||
* (meaning that the task has exit'ed, schedul_unload() will find the
|
||||
* data, unload the module, and free the structure.
|
||||
*
|
||||
* This function will add one structure to the linked list
|
||||
*
|
||||
* Input Parameter:
|
||||
* pid - The task ID of the child task
|
||||
* bin - This structure must have been allocated with kmalloc() and must
|
||||
* persist until the task unloads
|
||||
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void unload_list_add(pid_t pid, FAR struct binary_s *bin)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
/* Save the PID in the structure so that we recover it later */
|
||||
|
||||
bin->pid = pid;
|
||||
|
||||
/* Disable deliver of any signals while we muck with the list. The graceful
|
||||
* way to do this would be block delivery of SIGCHLD would be with
|
||||
* sigprocmask. Here we do it the quick'n'dirty way by just disabling
|
||||
* interrupts.
|
||||
*/
|
||||
|
||||
flags = irqsave();
|
||||
bin->flink = g_unloadhead;
|
||||
g_unloadhead = bin;
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: unload_list_remove
|
||||
*
|
||||
* Description:
|
||||
* If CONFIG_SCHED_HAVE_PARENT is defined then schedul_unload() will
|
||||
* manage instances of struct binary_s allocated with kmalloc. It
|
||||
* will keep the binary data in a link list and when SIGCHLD is received
|
||||
* (meaning that the task has exit'ed, schedul_unload() will find the
|
||||
* data, unload the module, and free the structure.
|
||||
*
|
||||
* This function will remove one structure to the linked list
|
||||
*
|
||||
* Input Parameter:
|
||||
* pid - The task ID of the child task
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, the load structure is returned. NULL is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static FAR struct binary_s *unload_list_remove(pid_t pid)
|
||||
{
|
||||
FAR struct binary_s *curr;
|
||||
FAR struct binary_s *prev;
|
||||
|
||||
/* Note the asymmetry. We do not have to disable interrupts here because
|
||||
* the main thread cannot run while we are in the interrupt handler. Here,
|
||||
* it should be sufficient to disable pre-emption so that no other thread
|
||||
* can run.
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Find the structure in the unload list with the matching PID */
|
||||
|
||||
for (prev = NULL, curr = g_unloadhead;
|
||||
curr && (curr->pid != pid);
|
||||
prev = curr, curr = curr->flink);
|
||||
|
||||
/* Did we find it? It must be there. Hmmm.. we should probably ASSERT if
|
||||
* we do not!
|
||||
*/
|
||||
|
||||
if (curr)
|
||||
{
|
||||
/* Was there another entry before this one? */
|
||||
|
||||
if (prev)
|
||||
{
|
||||
/* Yes.. remove the current entry from after the previous entry */
|
||||
|
||||
prev->flink = curr->flink;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No.. remove the current entry from the head of the list */
|
||||
|
||||
g_unloadhead = curr->flink;
|
||||
}
|
||||
|
||||
/* Nullify the forward link ... superstitious */
|
||||
|
||||
curr->flink = NULL;
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
return curr;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: unload_callback
|
||||
*
|
||||
* Description:
|
||||
* If CONFIG_SCHED_HAVE_PARENT is defined, this function may be called to
|
||||
* automatically unload the module when task exits. It assumes that
|
||||
* bin was allocated with kmalloc() or friends and will also automatically
|
||||
* free the structure with kfree() when the task exists.
|
||||
*
|
||||
* Input Parameter:
|
||||
* pid - The ID of the task that just exited
|
||||
* arg - A reference to the load structure cast to FAR void *
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void unload_callback(int signo, siginfo_t *info, void *ucontext)
|
||||
{
|
||||
FAR struct binary_s *bin;
|
||||
int ret;
|
||||
|
||||
/* Sanity checking */
|
||||
|
||||
if (!info || signo != SIGCHLD)
|
||||
{
|
||||
blldbg("ERROR:Bad signal callback: signo=%d info=%p\n", signo, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the load information for this pid */
|
||||
|
||||
bin = unload_list_remove(info->si_pid);
|
||||
if (!bin)
|
||||
{
|
||||
blldbg("ERROR: Could not find load info for PID=%d\n", info->si_pid);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Unload the module */
|
||||
|
||||
ret = unload_module(bin);
|
||||
if (ret < 0)
|
||||
{
|
||||
blldbg("ERROR: unload_module failed: %d\n", get_errno());
|
||||
}
|
||||
|
||||
/* Free the load structure */
|
||||
|
||||
kfree(bin);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: schedule_unload
|
||||
*
|
||||
* Description:
|
||||
* If CONFIG_SCHED_HAVE_PARENT is defined, this function may be called by
|
||||
* the parent of the the newly created task to automatically unload the
|
||||
* module when the task exits. This assumes that (1) the caller is the
|
||||
* parent of the created task, (2) that bin was allocated with kmalloc()
|
||||
* or friends. It will also automatically free the structure with kfree()
|
||||
* after unloading the module.
|
||||
*
|
||||
* Input Parameter:
|
||||
* pid - The task ID of the child task
|
||||
* bin - This structure must have been allocated with kmalloc() and must
|
||||
* persist until the task unloads
|
||||
*
|
||||
* Returned Value:
|
||||
* This is an end-user function, so it follows the normal convention:
|
||||
* It returns 0 (OK) if the callback was successfully scheduled. On
|
||||
* failure, it returns -1 (ERROR) and sets errno appropriately.
|
||||
*
|
||||
* On failures, the 'bin' structure will not be deallocated and the
|
||||
* module not not be unloaded.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int schedule_unload(pid_t pid, FAR struct binary_s *bin)
|
||||
{
|
||||
struct sigaction act;
|
||||
struct sigaction oact;
|
||||
sigset_t sigset;
|
||||
irqstate_t flags;
|
||||
int errorcode;
|
||||
int ret;
|
||||
|
||||
/* Make sure that SIGCHLD is unmasked */
|
||||
|
||||
(void)sigemptyset(&sigset);
|
||||
(void)sigaddset(&sigset, SIGCHLD);
|
||||
ret = sigprocmask(SIG_UNBLOCK, &sigset, NULL);
|
||||
if (ret != OK)
|
||||
{
|
||||
/* The errno value will get trashed by the following debug output */
|
||||
|
||||
errorcode = get_errno();
|
||||
bvdbg("ERROR: sigprocmask failed: %d\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
/* Add the structure to the list. We want to do this *before* connecting
|
||||
* the signal handler. This does, however, make error recovery more
|
||||
* complex if sigaction() fails below because then we have to remove the
|
||||
* unload structure for the list in an unexpected context.
|
||||
*/
|
||||
|
||||
unload_list_add(pid, bin);
|
||||
|
||||
/* Register the SIGCHLD handler */
|
||||
|
||||
act.sa_sigaction = unload_callback;
|
||||
act.sa_flags = SA_SIGINFO;
|
||||
|
||||
(void)sigfillset(&act.sa_mask);
|
||||
(void)sigdelset(&act.sa_mask, SIGCHLD);
|
||||
|
||||
ret = sigaction(SIGCHLD, &act, &oact);
|
||||
if (ret != OK)
|
||||
{
|
||||
/* The errno value will get trashed by the following debug output */
|
||||
|
||||
errorcode = get_errno();
|
||||
bvdbg("ERROR: sigaction failed: %d\n" , ret);
|
||||
|
||||
/* Emergency removal from the list */
|
||||
|
||||
flags = irqsave();
|
||||
if (unload_list_remove(pid) != bin)
|
||||
{
|
||||
blldbg("ERROR: Failed to remove structure\n");
|
||||
}
|
||||
|
||||
goto errout;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
errout:
|
||||
set_errno(errorcode);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_BINFMT_DISABLE && CONFIG_SCHED_HAVE_PARENT */
|
||||
|
|
@ -98,11 +98,11 @@ static int builtin_loadbinary(struct binary_s *binp)
|
|||
|
||||
/* Open the binary file for reading (only) */
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
fd = open(binp->filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
int errval = errno;
|
||||
bdbg("ERROR: Failed to open binary %s: %d\n", filename, errval);
|
||||
bdbg("ERROR: Failed to open binary %s: %d\n", binp->filename, errval);
|
||||
return -errval;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,13 +83,13 @@
|
|||
|
||||
FAR const char *builtin_getname(int index)
|
||||
{
|
||||
struct builtin_s *b;
|
||||
FAR const struct builtin_s *builtin;
|
||||
|
||||
b = builtin_for_index(index);
|
||||
builtin = builtin_for_index(index);
|
||||
|
||||
if (b != NULL)
|
||||
if (builtin != NULL)
|
||||
{
|
||||
return b->name;
|
||||
return builtin->name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -87,12 +87,12 @@
|
|||
|
||||
int builtin_isavail(FAR const char *appname)
|
||||
{
|
||||
FAR const char *n;
|
||||
FAR const char *name;
|
||||
int i;
|
||||
|
||||
for (i = 0; n = builtin_getname(i); i++)
|
||||
for (i = 0; (name = builtin_getname(i)); i++)
|
||||
{
|
||||
if (!strncmp(n, appname, NAME_MAX))
|
||||
if (!strncmp(name, appname, NAME_MAX))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -130,7 +130,8 @@ CONFIG_SDCLONE_DISABLE=y
|
|||
# CONFIG_SCHED_WORKQUEUE is not set
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
# CONFIG_SCHED_ATEXIT is not set
|
||||
# CONFIG_SCHED_ONEXIT is not set
|
||||
CONFIG_SCHED_ONEXIT=y
|
||||
CONFIG_SCHED_ONEXIT_MAX=1
|
||||
CONFIG_USER_ENTRYPOINT="nsh_main"
|
||||
CONFIG_DISABLE_OS_API=y
|
||||
# CONFIG_DISABLE_CLOCK is not set
|
||||
|
@ -259,7 +260,8 @@ CONFIG_MM_REGIONS=1
|
|||
# Binary Formats
|
||||
#
|
||||
# CONFIG_BINFMT_DISABLE is not set
|
||||
# CONFIG_BINFMT_EXEPATH is not set
|
||||
CONFIG_BINFMT_EXEPATH=y
|
||||
CONFIG_PATH_INITIAL="/bin"
|
||||
# CONFIG_NXFLAT is not set
|
||||
# CONFIG_ELF is not set
|
||||
CONFIG_BUILTIN=y
|
||||
|
@ -284,7 +286,10 @@ CONFIG_LIB_HOMEDIR="/"
|
|||
# CONFIG_EOL_IS_LF is not set
|
||||
# CONFIG_EOL_IS_BOTH_CRLF is not set
|
||||
CONFIG_EOL_IS_EITHER_CRLF=y
|
||||
# CONFIG_LIBC_EXECFUNCS is not set
|
||||
CONFIG_LIBC_EXECFUNCS=y
|
||||
CONFIG_EXECFUNCS_SYMTAB="g_symtab"
|
||||
CONFIG_EXECFUNCS_NSYMBOLS=0
|
||||
CONFIG_POSIX_SPAWN_STACKSIZE=1024
|
||||
# CONFIG_LIBC_STRERROR is not set
|
||||
# CONFIG_LIBC_PERROR_STDOUT is not set
|
||||
CONFIG_ARCH_LOWPUTC=y
|
||||
|
@ -410,6 +415,7 @@ CONFIG_EXAMPLES_NSH=y
|
|||
#
|
||||
CONFIG_NSH_LIBRARY=y
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_FILE_APPS=y
|
||||
|
||||
#
|
||||
# Disable Individual commands
|
||||
|
|
|
@ -265,7 +265,7 @@ int exec_module(FAR const struct binary_s *bin);
|
|||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
int schedule_unload(pid_t pid, FAR const struct binary_s *bin);
|
||||
int schedule_unload(pid_t pid, FAR struct binary_s *bin);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -77,6 +77,36 @@ extern "C" {
|
|||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: builtin_initialize
|
||||
*
|
||||
* Description:
|
||||
* Builtin support is built unconditionally. However, it order to
|
||||
* use this binary format, this function must be called during system
|
||||
* format in order to register the builtin binary format.
|
||||
*
|
||||
* Returned Value:
|
||||
* This is a NuttX internal function so it follows the convention that
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int builtin_initialize(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: builtin_uninitialize
|
||||
*
|
||||
* Description:
|
||||
* Unregister the builtin binary loader
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void builtin_uninitialize(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Utility Functions Provided to Applications by binfmt/libbuiltin
|
||||
****************************************************************************/
|
||||
|
|
|
@ -247,7 +247,7 @@ static int ps_exec(FAR pid_t *pidp, FAR const char *path,
|
|||
|
||||
errout:
|
||||
sched_unlock();
|
||||
return OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -116,7 +116,7 @@ int main(int argc, char **argv, char **envp)
|
|||
printf(" * configured (at present, NXFLAT is the only supported binary.\n");
|
||||
printf(" * format).\n");
|
||||
printf(" */\n\n");
|
||||
printf("#if !defined(CONFIG_NXFLAT) && !defined(CONFIG_ELF)\n");
|
||||
printf("#if !defined(CONFIG_NXFLAT) && !defined(CONFIG_ELF) && !defined(CONFIG_BUILTIN)\n");
|
||||
printf("# undef CONFIG_BINFMT_DISABLE\n");
|
||||
printf("# define CONFIG_BINFMT_DISABLE 1\n");
|
||||
printf("#endif\n\n");
|
||||
|
|
Loading…
Reference in New Issue