summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-12-16 21:15:27 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-12-16 21:15:27 +0000
commit3dfe9f3ba541f759e690bc112cb9025737970d5a (patch)
tree966aa2197272d9b52e3e25177cd78cea2751ade2
parent2fe1350cbd4c9deefa22a2c5785621a258e7a81c (diff)
downloadnuttx-3dfe9f3ba541f759e690bc112cb9025737970d5a.tar.gz
nuttx-3dfe9f3ba541f759e690bc112cb9025737970d5a.tar.bz2
nuttx-3dfe9f3ba541f759e690bc112cb9025737970d5a.zip
Add basic hooks to support a PATH variable (more is needed)
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5440 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/ChangeLog9
-rw-r--r--nuttx/TODO28
-rw-r--r--nuttx/binfmt/Kconfig16
-rw-r--r--nuttx/binfmt/Makefile16
-rw-r--r--nuttx/binfmt/binfmt_exepath.c285
-rw-r--r--nuttx/configs/sim/ostest/defconfig21
-rw-r--r--nuttx/include/nuttx/binfmt/binfmt.h112
-rw-r--r--nuttx/sched/env_clearenv.c2
-rw-r--r--nuttx/sched/env_release.c4
-rw-r--r--nuttx/sched/os_bringup.c19
-rw-r--r--nuttx/sched/os_start.c4
11 files changed, 485 insertions, 31 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 11e8b200b..c61b28f69 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -3782,4 +3782,13 @@
* arch/z80/src/z180/z180_mmu.*: Add MMU support for z180 tasks.
* configs/p112: Add very basic board support and an examples/ostest
configuration for the venerable P112 board.
+ * sched/os_bringup.c: If CONFIG_PATH_INITIAL is defined, then the initial
+ environment of the task started by os_bringup() will have the PATH
+ environment variable defined to be that string.
+ * binfmt/binfmt_exepath.c: If CONFIG_BINFMT_EXEPATH is defined, then this
+ file will be built. In contains logic to search for regular files at
+ the absolutes paths found in the current PATH environment variable
+ setting. This is untested and not yet hooked into the binfmt exec()
+ logic on initial check-in
+
diff --git a/nuttx/TODO b/nuttx/TODO
index fcc418a0e..85a89b41f 100644
--- a/nuttx/TODO
+++ b/nuttx/TODO
@@ -35,12 +35,12 @@ nuttx/
(4) ARM/STM32 (arch/arm/src/stm32/)
(3) AVR (arch/avr)
(0) Intel x86 (arch/x86)
- (4) 8051 / MCS51 (arch/8051/)
+ (5) 8051 / MCS51 (arch/8051/)
(3) MIPS/PIC32 (arch/mips)
(1) Hitachi/Renesas SH-1 (arch/sh/src/sh1)
(4) Renesas M16C/26 (arch/sh/src/m16c)
(10) z80/z8/ez80 (arch/z80/)
- (8) z16 (arch/z16/)
+ (9) z16 (arch/z16/)
(1) mc68hc1x (arch/hc)
apps/
@@ -1505,6 +1505,16 @@ o 8051 / MCS51 (arch/8051/)
Status: Open
Priority: Low -- only because there as so many other issues with 8051
+ Title: 8051 BUILD BROKEN
+ Description: The last time I tried to build the pjrc-8051 configurtion using
+ the SDCC 3.2.1 toolchain (for Windows). I got compilation
+ errors in sched/os_bringup.c. It complained about type
+ mis-matches. What I gather from Googling, this is a problem
+ with the --stack-auto option. At any rate, this problem will
+ need to be fixed if you want to resurrect the 8051 NuttX port.
+ Status: Open
+ Priority: Low -- I don't think anyone uses the 8051 port.
+
o MIPS/PIC32(arch/mips)
^^^^^^^^^^^^^^^^^^^^^
@@ -1833,9 +1843,17 @@ o z16 (arch/z16)
Internal Error(0503) On line 2504 of "MMCSD\MMCSD_SDIO.C"
File <c3>, Args(562,46)
- Status: Open. Recommended workaround: remove mmcsd_sdio.c from
- drivers/mmcsd/Make.defs. There is no SDIO support for the Z16 anyway
- Priority: Low
+ Status: Open. Recommended workaround: remove mmcsd_sdio.c from
+ drivers/mmcsd/Make.defs. There is no SDIO support for the Z16 anyway
+ Priority: Low
+
+ Title: NATIVE BUILD PROBLEMS
+ Description: When last tested (ca.12/12), there were some missing .obj files in
+ arch/z16/src. A little additional TLC will be needed to get a
+ reliable Windows native build. As of this writing, the Cygwin
+ based build has not been re-verified.
+ Status: Open
+ Priority: Low -- I don't think anyone uses the Z16 port.
o mc68hc1x (arch/hc)
^^^^^^^^^^^^^^^^^^
diff --git a/nuttx/binfmt/Kconfig b/nuttx/binfmt/Kconfig
index cbf909327..495bd050f 100644
--- a/nuttx/binfmt/Kconfig
+++ b/nuttx/binfmt/Kconfig
@@ -12,6 +12,22 @@ config BINFMT_DISABLE
if !BINFMT_DISABLE
+config BINFMT_EXEPATH
+ bool "Support PATH variable"
+ default n
+ depends on !DISABLE_ENVIRON
+ ---help---
+ Use the contents of the PATH environment variable to locate executable
+ files. Default: n
+
+config PATH_INITIAL
+ string "Initial PATH Value"
+ default ""
+ depends on BINFMT_EXEPATH
+ ---help---
+ The initial value of the PATH variable. This is the colon-separated
+ list of absolute paths. E.g., "/bin:/usr/bin:/sbin"
+
config NXFLAT
bool "Enable the NXFLAT Binary Format"
default n
diff --git a/nuttx/binfmt/Makefile b/nuttx/binfmt/Makefile
index bda9602ac..8ec0d877c 100644
--- a/nuttx/binfmt/Makefile
+++ b/nuttx/binfmt/Makefile
@@ -43,15 +43,19 @@ CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" "$(TOPDIR)$(DELIM)sched"}
# Basic BINFMT source files
-BINFMT_ASRCS =
-BINFMT_CSRCS = binfmt_globals.c binfmt_register.c binfmt_unregister.c \
- binfmt_loadmodule.c binfmt_unloadmodule.c binfmt_execmodule.c \
- binfmt_exec.c binfmt_dumpmodule.c
+BINFMT_ASRCS =
+BINFMT_CSRCS = binfmt_globals.c binfmt_register.c binfmt_unregister.c
+BINFMT_CSRCS += binfmt_loadmodule.c binfmt_unloadmodule.c binfmt_execmodule.c
+BINFMT_CSRCS += binfmt_exec.c binfmt_dumpmodule.c
+
+ifeq ($(CONFIG_BINFMT_EXEPATH),y)
+BINFMT_CSRCS += binfmt_exepath.c
+endif
# Symbol table source files
-BINFMT_CSRCS += symtab_findbyname.c symtab_findbyvalue.c \
- symtab_findorderedbyname.c symtab_findorderedbyvalue.c
+BINFMT_CSRCS += symtab_findbyname.c symtab_findbyvalue.c
+BINFMT_CSRCS += symtab_findorderedbyname.c symtab_findorderedbyvalue.c
# Add configured binary modules
diff --git a/nuttx/binfmt/binfmt_exepath.c b/nuttx/binfmt/binfmt_exepath.c
new file mode 100644
index 000000000..c81588975
--- /dev/null
+++ b/nuttx/binfmt/binfmt_exepath.c
@@ -0,0 +1,285 @@
+/****************************************************************************
+ * binfmt/binfmt_exepath.c
+ *
+ * Copyright (C) 2012 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 <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/binfmt/binfmt.h>
+
+#if !defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_BINFMT_EXEPATH)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct exepath_s
+{
+ FAR char *next; /* Pointer to the next (unterminated) value in the PATH variable */
+ char path[1];
+};
+#define SIZEOF_EXEPATH_S(n) (sizeof(struct exepath_s) + (n) - 1)
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: exepath_init
+ *
+ * Description:
+ * Initialize for the traversal of each value in the PATH variable. The
+ * usage is sequence is as follows:
+ *
+ * 1) Call exepath_init() to initialze for the traversal. exepath_init()
+ * will return an opaque handle that can then be provided to
+ * exepath_next() and exepath_release().
+ * 2) Call exepath_next() repeatedly to examine every file that lies
+ * in the directories of the PATH variable
+ * 3) Call exepath_release() to free resources set aside by exepath_init().
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, exepath_init() return a non-NULL, opaque handle that may
+ * subsequently be used in calls to exepath_next() and exepath_release().
+ * On error, a NULL handle value will be returned. The most likely cause
+ * of an error would be that the there is no value associated with the
+ * PATH variable.
+ *
+ ****************************************************************************/
+
+EXEPATH_HANDLE exepath_init(void)
+{
+ FAR struct exepath_s *exepath;
+ FAR char *path;
+
+ /* Get the value of the PATH variable */
+
+ path = getenv("PATH");
+ if (!path)
+ {
+ /* getenv() will return a NULL value if the PATH variable does not
+ * exist in the environment.
+ */
+
+ return (EXEPATH_HANDLE)NULL;
+ }
+
+ /* Allocate a container for the PATH variable contents */
+
+ exepath = (FAR struct exepath_s *)kmalloc(SIZEOF_EXEPATH_S(strlen(path) + 1));
+ if (!exepath)
+ {
+ /* Ooops.. we are out of memory */
+
+ return (EXEPATH_HANDLE)NULL;
+ }
+
+ /* Populate the container */
+
+ strcpy(exepath->path, path);
+ exepath->next = exepath->path;
+
+ /* And return the containing cast to an opaque handle */
+
+ return (EXEPATH_HANDLE)exepath;
+}
+
+ /****************************************************************************
+ * Name: exepath_next
+ *
+ * Description:
+ * Traverse all possible values in the PATH variable in attempt to find
+ * the full path to an executable file when only a relative path is
+ * provided.
+ *
+ * Input Parameters:
+ * handle - The handle value returned by exepath_init
+ * relpath - The relative path to the file to be found.
+ *
+ * Returned Value:
+ * On success, a non-NULL pointer to a null-terminated string is provided.
+ * This is the full path to a file that exists in the file system. This
+ * function will verify that the file exists (but will not verify that it
+ * is marked executable).
+ *
+ * NOTE: The string pointer return in the success case points to allocated
+ * memory. This memory must be freed by the called by calling kfree().
+ *
+ * NULL is returned if no path is found to any file with the provided
+ * 'relpath' from any absolute path in the file variable. In this case,
+ * there is no point in calling exepath_next() further; exepath_release()
+ * must be called to release resources set aside by expath_init().
+ *
+ ****************************************************************************/
+
+FAR char *exepath_next(EXEPATH_HANDLE handle, FAR const char *relpath)
+{
+ FAR struct exepath_s *exepath = (FAR struct exepath_s *)handle;
+ struct stat buf;
+ FAR char *endptr;
+ FAR char *path;
+ FAR char *fullpath;
+ int pathlen;
+ int ret;
+
+ /* Verify that a value handle and relative path were provided */
+
+ DEBUGASSERT(exepath && relpath);
+ DEBUGASSERT(relpath[0] != '\0' && relpath[0] != '/');
+
+ /* Loop until (1) we find a file with this relative path from one of the
+ * absolute paths in the PATH variable, or (2) all of the absolute paths
+ * in the PATH variable have been considered.
+ */
+
+ for (;;)
+ {
+ /* Make sure that exepath->next points to the beginning of a string */
+
+ path = exepath->next;
+ if (*path == '\0')
+ {
+ /* If it points to a NULL it means that either (1) the PATH varialbe
+ * is empty, or (2) we have already examined all of the paths in the
+ * path variable.
+ */
+
+ return (FAR char *)NULL;
+ }
+
+ /* Okay... 'path' points to the beginning of the string. The string may
+ * be termined either with (1) ':' which separates the path from the
+ * next path in the list, or (2) NUL which marks the end of the list.
+ */
+
+ endptr = strchr(path, ':');
+ if (!endptr)
+ {
+ /* If strchr returns NUL it means that ':' does not appear in the
+ * string. Therefore, this must be the final path in the PATH
+ * variable content.
+ */
+
+ endptr = &path[strlen(path)];
+ exepath->next = endptr;
+ DEBUGASSERT(*endptr == '\0');
+ }
+ else
+ {
+ DEBUGASSERT(*endptr == ':');
+ exepath->next = endptr + 1;
+ *endptr = '\0';
+ }
+
+ pathlen = strlen(path) + strlen(relpath) + 2;
+ fullpath = (FAR char *)kmalloc(pathlen);
+ if (!fullpath)
+ {
+ /* Failed to allocate memory */
+
+ return (FAR char *)NULL;
+ }
+
+ /* Construct the full path */
+
+ sprintf(fullpath, "%s/%s", path, relpath);
+
+ /* Verify that a regular file exists at this path */
+
+ ret = stat(fullpath, &buf);;
+ if (ret == OK && S_ISREG(buf.st_mode))
+ {
+ return fullpath;
+ }
+
+ /* Failed to stat the file. Just free the allocated memory and
+ * continue to try the next path.
+ */
+
+ kfree(fullpath);
+ }
+
+ /* We will not get here */
+}
+
+/****************************************************************************
+ * Name: exepath_release
+ *
+ * Description:
+ * Release all resources set aside by exepath_release when the handle value
+ * was created. The handle value is invalid on return from this function.
+ * Attempts to all exepath_next() or exepath_release() with such a 'stale'
+ * handle will result in undefined (i.e., not good) behavior.
+ *
+ * Input Parameters:
+ * handle - The handle value returned by exepath_init
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void exepath_release(EXEPATH_HANDLE handle)
+{
+ kfree(handle);
+}
+
+#endif /* !CONFIG_BINFMT_DISABLE && CONFIG_BINFMT_EXEPATH */
+
diff --git a/nuttx/configs/sim/ostest/defconfig b/nuttx/configs/sim/ostest/defconfig
index aece17569..beee30639 100644
--- a/nuttx/configs/sim/ostest/defconfig
+++ b/nuttx/configs/sim/ostest/defconfig
@@ -8,6 +8,10 @@ CONFIG_NUTTX_NEWCONFIG=y
# Build Setup
#
# CONFIG_EXPERIMENTAL is not set
+CONFIG_HOST_LINUX=y
+# CONFIG_HOST_OSX is not set
+# CONFIG_HOST_WINDOWS is not set
+# CONFIG_HOST_OTHER is not set
#
# Build Configuration
@@ -83,7 +87,11 @@ CONFIG_BOARD_LOOPSPERMSEC=100
#
# CONFIG_ARCH_NOINTC is not set
# CONFIG_ARCH_DMA is not set
+# CONFIG_ARCH_IRQPRIO is not set
+# CONFIG_CUSTOM_STACK is not set
+# CONFIG_ADDRENV is not set
# CONFIG_ARCH_STACKDUMP is not set
+# CONFIG_ENDIAN_BIG is not set
#
# Board Settings
@@ -165,7 +173,6 @@ CONFIG_PREALLOC_TIMERS=8
#
# Stack and heap information
#
-# CONFIG_CUSTOM_STACK is not set
CONFIG_IDLETHREAD_STACKSIZE=4096
CONFIG_USERMAIN_STACKSIZE=4096
CONFIG_PTHREAD_STACK_MIN=256
@@ -250,8 +257,10 @@ CONFIG_MM_REGIONS=1
# Binary Formats
#
# CONFIG_BINFMT_DISABLE is not set
+# CONFIG_BINFMT_EXEPATH is not set
# CONFIG_NXFLAT is not set
# CONFIG_ELF is not set
+# CONFIG_PIC is not set
# CONFIG_SYMTAB_ORDEREDBYNAME is not set
#
@@ -274,9 +283,12 @@ CONFIG_ARCH_LOWPUTC=y
CONFIG_LIB_SENDFILE_BUFSIZE=512
# CONFIG_ARCH_ROMGETC is not set
# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set
+
+#
+# Basic CXX Support
+#
+# CONFIG_C99_BOOL8 is not set
# CONFIG_HAVE_CXX is not set
-# CONFIG_HAVE_CXXINITIALIZE is not set
-# CONFIG_CXX_NEWLONG is not set
#
# Application Configuration
@@ -302,6 +314,7 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512
# CONFIG_EXAMPLES_HELLOXX is not set
# CONFIG_EXAMPLES_JSON is not set
# CONFIG_EXAMPLES_HIDKBD is not set
+# CONFIG_EXAMPLES_KEYPADTEST is not set
# CONFIG_EXAMPLES_IGMP is not set
# CONFIG_EXAMPLES_LCDRW is not set
# CONFIG_EXAMPLES_MM is not set
@@ -323,6 +336,8 @@ CONFIG_EXAMPLES_OSTEST=y
CONFIG_EXAMPLES_OSTEST_LOOPS=100
CONFIG_EXAMPLES_OSTEST_STACKSIZE=8192
CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS=8
+CONFIG_EXAMPLES_OSTEST_RR_RANGE=10000
+CONFIG_EXAMPLES_OSTEST_RR_RUNS=10
# CONFIG_EXAMPLES_PASHELLO is not set
# CONFIG_EXAMPLES_PIPE is not set
# CONFIG_EXAMPLES_POLL is not set
diff --git a/nuttx/include/nuttx/binfmt/binfmt.h b/nuttx/include/nuttx/binfmt/binfmt.h
index 49ab37264..80c0e7c7b 100644
--- a/nuttx/include/nuttx/binfmt/binfmt.h
+++ b/nuttx/include/nuttx/binfmt/binfmt.h
@@ -54,6 +54,14 @@
/****************************************************************************
* Public Types
****************************************************************************/
+/* EXEPATH_HANDLE is an opaque handle used to traverse the absolute paths
+ * assigned to the PATH environment variable.
+ */
+
+#if !defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_BINFMT_EXEPATH)
+typedef FAR void *EXEPATH_HANDLE;
+#endif
+
/* The type of one C++ constructor or destructor */
typedef FAR void (*binfmt_ctor_t)(void);
@@ -100,12 +108,9 @@ struct binfmt_s
* Public Data
****************************************************************************/
-#undef EXTERN
#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
+extern "C"
+{
#endif
/****************************************************************************
@@ -125,7 +130,7 @@ extern "C" {
*
****************************************************************************/
-EXTERN int register_binfmt(FAR struct binfmt_s *binfmt);
+int register_binfmt(FAR struct binfmt_s *binfmt);
/****************************************************************************
* Name: unregister_binfmt
@@ -140,7 +145,7 @@ EXTERN int register_binfmt(FAR struct binfmt_s *binfmt);
*
****************************************************************************/
-EXTERN int unregister_binfmt(FAR struct binfmt_s *binfmt);
+int unregister_binfmt(FAR struct binfmt_s *binfmt);
/****************************************************************************
* Name: load_module
@@ -156,7 +161,7 @@ EXTERN int unregister_binfmt(FAR struct binfmt_s *binfmt);
*
****************************************************************************/
-EXTERN int load_module(FAR struct binary_s *bin);
+int load_module(FAR struct binary_s *bin);
/****************************************************************************
* Name: unload_module
@@ -177,7 +182,7 @@ EXTERN int load_module(FAR struct binary_s *bin);
*
****************************************************************************/
-EXTERN int unload_module(FAR const struct binary_s *bin);
+int unload_module(FAR const struct binary_s *bin);
/****************************************************************************
* Name: exec_module
@@ -192,7 +197,7 @@ EXTERN int unload_module(FAR const struct binary_s *bin);
*
****************************************************************************/
-EXTERN int exec_module(FAR const struct binary_s *bin, int priority);
+int exec_module(FAR const struct binary_s *bin, int priority);
/****************************************************************************
* Name: exec
@@ -214,8 +219,91 @@ EXTERN int exec_module(FAR const struct binary_s *bin, int priority);
*
****************************************************************************/
-EXTERN int exec(FAR const char *filename, FAR const char **argv,
- FAR const struct symtab_s *exports, int nexports);
+int exec(FAR const char *filename, FAR const char **argv,
+ FAR const struct symtab_s *exports, int nexports);
+
+/****************************************************************************
+ * Name: exepath_init
+ *
+ * Description:
+ * Initialize for the traversal of each value in the PATH variable. The
+ * usage is sequence is as follows:
+ *
+ * 1) Call exepath_init() to initialze for the traversal. exepath_init()
+ * will return an opaque handle that can then be provided to
+ * exepath_next() and exepath_release().
+ * 2) Call exepath_next() repeatedly to examine every file that lies
+ * in the directories of the PATH variable
+ * 3) Call exepath_release() to free resources set aside by exepath_init().
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * On success, exepath_init() return a non-NULL, opaque handle that may
+ * subsequently be used in calls to exepath_next() and exepath_release().
+ * On error, a NULL handle value will be returned. The most likely cause
+ * of an error would be that the there is no value associated with the
+ * PATH variable.
+ *
+ ****************************************************************************/
+
+#if !defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_BINFMT_EXEPATH)
+EXEPATH_HANDLE exepath_init(void);
+#endif
+
+ /****************************************************************************
+ * Name: exepath_next
+ *
+ * Description:
+ * Traverse all possible values in the PATH variable in attempt to find
+ * the full path to an executable file when only a relative path is
+ * provided.
+ *
+ * Input Parameters:
+ * handle - The handle value returned by exepath_init
+ * relpath - The relative path to the file to be found.
+ *
+ * Returned Value:
+ * On success, a non-NULL pointer to a null-terminated string is provided.
+ * This is the full path to a file that exists in the file system. This
+ * function will verify that the file exists (but will not verify that it
+ * is marked executable).
+ *
+ * NOTE: The string pointer return in the success case points to allocated
+ * memory. This memory must be freed by the called by calling kfree().
+ *
+ * NULL is returned if no path is found to any file with the provided
+ * 'relpath' from any absolute path in the file variable. In this case,
+ * there is no point in calling exepath_next() further; exepath_release()
+ * must be called to release resources set aside by expath_init().
+ *
+ ****************************************************************************/
+
+#if !defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_BINFMT_EXEPATH)
+FAR char *exepath_next(EXEPATH_HANDLE handle, FAR const char *relpath);
+#endif
+
+/****************************************************************************
+ * Name: exepath_release
+ *
+ * Description:
+ * Release all resources set aside by exepath_release when the handle value
+ * was created. The handle value is invalid on return from this function.
+ * Attempts to all exepath_next() or exepath_release() with such a 'stale'
+ * handle will result in undefined (i.e., not good) behavior.
+ *
+ * Input Parameters:
+ * handle - The handle value returned by exepath_init
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+#if !defined(CONFIG_BINFMT_DISABLE) && defined(CONFIG_BINFMT_EXEPATH)
+void exepath_release(EXEPATH_HANDLE handle);
+#endif
#undef EXTERN
#if defined(__cplusplus)
diff --git a/nuttx/sched/env_clearenv.c b/nuttx/sched/env_clearenv.c
index 7fe97a911..75890f3bc 100644
--- a/nuttx/sched/env_clearenv.c
+++ b/nuttx/sched/env_clearenv.c
@@ -79,5 +79,3 @@ int clearenv(void)
#endif /* CONFIG_DISABLE_ENVIRON */
-
-
diff --git a/nuttx/sched/env_release.c b/nuttx/sched/env_release.c
index 83e65dbb5..8bc8d2205 100644
--- a/nuttx/sched/env_release.c
+++ b/nuttx/sched/env_release.c
@@ -94,11 +94,11 @@ int env_release(FAR _TCB *ptcb)
{
/* Check the reference count on the environment structure */
- if ( envp->ev_crefs <= 1)
+ if (envp->ev_crefs <= 1)
{
/* Decrementing the reference count will destroy the environment */
- sched_free( envp ); /* plain free() should be fine here */
+ sched_free(envp);
}
else
{
diff --git a/nuttx/sched/os_bringup.c b/nuttx/sched/os_bringup.c
index ec6152891..e0a236bbe 100644
--- a/nuttx/sched/os_bringup.c
+++ b/nuttx/sched/os_bringup.c
@@ -44,6 +44,7 @@
#include <nuttx/config.h>
#include <sched.h>
+#include <stdlib.h>
#include <debug.h>
#include <nuttx/init.h>
@@ -129,6 +130,17 @@ int os_bringup(void)
#endif
int init_taskid;
+ /* Setup up the initial environment for the idle task. At present, this
+ * may consist of only the initial PATH variable. The PATH variable is
+ * (probably) not used by the IDLE task. However, the environment
+ * containing the PATH variable will be inherited by all of the threads
+ * created by the IDLE task.
+ */
+
+#if !defined(CONFIG_DISABLE_ENVIRON) && defined(CONFIG_PATH_INITIAL)
+ (void)setenv("PATH", CONFIG_PATH_INITIAL, 1);
+#endif
+
/* Start the page fill worker kernel thread that will resolve page faults.
* This should always be the first thread started because it may have to
* resolve page faults in other threads
@@ -190,5 +202,12 @@ int os_bringup(void)
(main_t)CONFIG_USER_ENTRYPOINT, (const char **)NULL);
#endif
ASSERT(init_taskid != ERROR);
+
+ /* We an save a few bytes by discarding the IDLE thread's environment. */
+
+#if !defined(CONFIG_DISABLE_ENVIRON) && defined(CONFIG_PATH_INITIAL)
+ (void)clearenv();
+#endif
+
return OK;
}
diff --git a/nuttx/sched/os_start.c b/nuttx/sched/os_start.c
index c0b16236d..a53ac2aa8 100644
--- a/nuttx/sched/os_start.c
+++ b/nuttx/sched/os_start.c
@@ -426,7 +426,9 @@ void os_start(void)
lib_initialize();
}
- /* Create stdout, stderr, stdin */
+ /* Create stdout, stderr, stdin on the IDLE task. These will be
+ * inherited by all of the threads created by the IDLE task.
+ */
(void)sched_setupidlefiles(&g_idletcb);