aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorpx4dev <px4@purgatory.org>2013-01-23 18:58:19 -0800
committerpx4dev <px4@purgatory.org>2013-01-23 18:58:19 -0800
commitdc88dd0abb440b070e87337a7da6fd7a4c39311c (patch)
tree00260c9b8b5d6f20983f1ffbe211c39c87bd2b85 /apps
parentd8a013f8720e81afb637b8206fbe521ccb43ac8f (diff)
parent1ce1d4460b1c7884490118ea356bf61ffbd31163 (diff)
downloadpx4-firmware-dc88dd0abb440b070e87337a7da6fd7a4c39311c.tar.gz
px4-firmware-dc88dd0abb440b070e87337a7da6fd7a4c39311c.tar.bz2
px4-firmware-dc88dd0abb440b070e87337a7da6fd7a4c39311c.zip
Merge branch 'master' into px4io-i2c
Diffstat (limited to 'apps')
-rw-r--r--apps/ChangeLog.txt50
-rw-r--r--apps/Kconfig4
-rw-r--r--apps/Make.defs15
-rw-r--r--apps/Makefile43
-rw-r--r--apps/README.txt146
-rw-r--r--apps/builtin/Kconfig17
-rw-r--r--apps/builtin/Make.defs (renamed from apps/namedapp/Make.defs)6
-rw-r--r--apps/builtin/Makefile (renamed from apps/namedapp/Makefile)64
-rw-r--r--apps/builtin/builtin.c (renamed from apps/namedapp/namedapp.c)15
-rw-r--r--apps/builtin/exec_builtin.c423
-rw-r--r--apps/builtin/registry/Makefile61
-rw-r--r--apps/examples/Kconfig2
-rw-r--r--apps/examples/Make.defs8
-rw-r--r--apps/examples/Makefile28
-rw-r--r--apps/examples/README.txt104
-rw-r--r--apps/examples/adc/Makefile9
-rw-r--r--apps/examples/buttons/Makefile9
-rw-r--r--apps/examples/can/Makefile9
-rw-r--r--apps/examples/cdcacm/Makefile11
-rw-r--r--apps/examples/hello/Makefile11
-rw-r--r--apps/examples/helloxx/Makefile9
-rw-r--r--apps/examples/ostest/Makefile17
-rw-r--r--apps/examples/ostest/ostest.h46
-rw-r--r--apps/examples/ostest/ostest_main.c14
-rw-r--r--apps/examples/ostest/sighand.c63
-rw-r--r--apps/examples/ostest/vfork.c (renamed from apps/namedapp/namedapp.h)75
-rw-r--r--apps/examples/ostest/waitpid.c269
-rw-r--r--apps/examples/posix_spawn/Kconfig29
-rw-r--r--apps/examples/posix_spawn/Makefile130
-rw-r--r--apps/examples/posix_spawn/filesystem/Makefile88
-rw-r--r--apps/examples/posix_spawn/filesystem/hello/hello.c78
-rwxr-xr-xapps/examples/posix_spawn/filesystem/mksymtab.sh51
-rw-r--r--apps/examples/posix_spawn/filesystem/redirect/redirect.c63
-rw-r--r--apps/examples/posix_spawn/filesystem/testdata.txt2
-rw-r--r--apps/examples/posix_spawn/spawn_main.c460
-rw-r--r--apps/examples/pwm/Makefile9
-rw-r--r--apps/examples/qencoder/Makefile9
-rw-r--r--apps/examples/watchdog/Makefile9
-rw-r--r--apps/include/builtin.h (renamed from apps/include/apps.h)92
-rw-r--r--apps/interpreters/Makefile2
-rw-r--r--apps/interpreters/ficl/Makefile1
-rw-r--r--apps/namedapp/Kconfig15
-rw-r--r--apps/namedapp/binfs.c596
-rw-r--r--apps/namedapp/exec_namedapp.c187
-rw-r--r--apps/namedapp/namedapp_list.h42
-rw-r--r--apps/namedapp/namedapp_proto.h42
-rw-r--r--apps/nshlib/Kconfig8
-rw-r--r--apps/nshlib/Makefile3
-rw-r--r--apps/nshlib/README.txt2
-rw-r--r--apps/nshlib/nsh.h3
-rw-r--r--apps/nshlib/nsh_builtin.c (renamed from apps/nshlib/nsh_apps.c)31
-rw-r--r--apps/nshlib/nsh_codeccmd.c538
-rw-r--r--apps/nshlib/nsh_mntcmds.c77
-rw-r--r--apps/nshlib/nsh_netcmds.c1
-rw-r--r--apps/nshlib/nsh_parse.c103
-rw-r--r--apps/system/Makefile2
-rw-r--r--apps/system/free/Makefile10
-rw-r--r--apps/system/i2c/Makefile12
-rw-r--r--apps/system/install/Makefile10
-rw-r--r--apps/system/readline/Makefile1
-rw-r--r--apps/systemcmds/perf/perf.c10
-rw-r--r--apps/systemlib/perf_counter.c45
-rw-r--r--apps/systemlib/perf_counter.h13
63 files changed, 3124 insertions, 1178 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt
index 0695747f8..14eb78950 100644
--- a/apps/ChangeLog.txt
+++ b/apps/ChangeLog.txt
@@ -435,3 +435,53 @@
logic to find the absolute path to the program using the PATH variable.
6.25 2013-xx-xx Gregory Nutt <gnutt@nuttx.org>
+
+ * Makefiles: Removed dependency of distclean on clean in most top-level
+ files. It makes sense for 'leaf' Makefiles to have this dependency,
+ but it does not make sense for upper-level Makefiles.
+ * apps/namedapp/: Renamed to builtins in preparation for another change.
+ * .context: Removed the .context kludge. This caused lots of problems
+ when changing configurations because there is no easy way to get the
+ system to rebuild the context. Now, the context will be rebuilt
+ whenever there is a change in either .config or the Makefile.
+ * apps/builtin/registry: Updated new built-in registration logic to handle
+ cases where (1) old apps/.config is used, and (2) applications ared
+ removed, not just added.
+ * apps/examples/nettest/Makefile: Fix an error that crept in during
+ some of the recent, massive build system changes.
+ * apps/builtin/Makefile: Need to have auto-generated header files
+ in place early in the dependency generation phase to avoid warnings.
+ It is not important if they are only stubbed out header files at
+ this build phase.
+ * apps/examples/hidbkd: Now supports decoding of encoded special keys
+ if CONFIG_EXAMPLES_HIDKBD_ENCODED is defined.
+ * apps/examples/hidbkd: Add support for decoding key release events
+ as well. However, the USB HID keyboard drier has not yet been
+ updated to detect key release events. That is kind of tricky in
+ the USB HID keyboard report data.
+ * apps/examples/wlan: Remove non-functional example.
+ * apps/examples/ostest/vfork.c: Added a test of vfork().
+ * apps/exampes/posix_spawn: Added a test of poxis_spawn().
+ * apps/examples/ostest: Extend signal handler test to catch
+ death-of-child signals (SIGCHLD).
+ * apps/examples/ostest/waitpid.c: Add a test for waitpid(), waitid(),
+ and wait().
+ * builtin/binfs.c: Add hooks for dup() method (not implemented).
+ * builtin/exec_builtin.c, nshlib/nsh_parse.c, and nshlib/nsh_builtin.c:
+ NSH now supports re-direction of I/O to files (but still not from).
+ * builtin/binfs.c: Greatly simplified (it is going to need to be
+ very lightweight). Now supports open, close, and a new ioctl to recover
+ the builtin filename. The latter will be needed to support a binfs
+ binfmt.
+ * builtin/binfs.c: Move apps/builtin/binfs.c to fs/binfs/fs_binfs.c
+ CONFIG_APPS_BINDIR rename CONFIG_FS_BINFS
+ * apps/include/builtin.h: Some of the content of
+ apps/include/apps.h moved to include/nuttx/binfmt/builtin.h.
+ apps/include/apps.h renamed builtin.h
+ * apps/builtin/exec_builtins.c: Move utility builtin
+ utility functions from apps/builtin/exec_builtins.c to
+ binfmt/libbuiltin/libbuiltin_utils.c
+ * apps/nshlib/nsh_mountcmds.c: The block driver/source
+ 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.
diff --git a/apps/Kconfig b/apps/Kconfig
index ea9bd2d31..68c36f5a5 100644
--- a/apps/Kconfig
+++ b/apps/Kconfig
@@ -3,8 +3,8 @@
# see misc/tools/kconfig-language.txt.
#
-menu "Named Applications"
-source "$APPSDIR/namedapp/Kconfig"
+menu "Built-In Applications"
+source "$APPSDIR/builtin/Kconfig"
endmenu
menu "Examples"
diff --git a/apps/Make.defs b/apps/Make.defs
index 53ac7f8be..f7e6aa08d 100644
--- a/apps/Make.defs
+++ b/apps/Make.defs
@@ -34,8 +34,17 @@
#
############################################################################
+BUILTIN_REGISTRY = $(APPDIR)$(DELIM)builtin$(DELIM)registry
+
+ifeq ($(CONFIG_NUTTX_NEWCONFIG),y)
+DEPCONFIG = $(TOPDIR)$(DELIM).config
+else
+DEPCONFIG = $(TOPDIR)$(DELIM).config $(APPDIR)$(DELIM).config
+endif
+
define REGISTER
- @echo "Register: $1"
- @echo "{ \"$1\", $2, $3, $4 }," >> "$(APPDIR)/namedapp/namedapp_list.h"
- @echo "EXTERN int $4(int argc, char *argv[]);" >> "$(APPDIR)/namedapp/namedapp_proto.h"
+ $(Q) echo "Register: $1"
+ $(Q) echo "{ \"$1\", $2, $3, $4 }," > "$(BUILTIN_REGISTRY)$(DELIM)$4.bdat"
+ $(Q) echo "int $4(int argc, char *argv[]);" > "$(BUILTIN_REGISTRY)$(DELIM)$4.pdat"
+ $(Q) touch "$(BUILTIN_REGISTRY)$(DELIM).updated"
endef
diff --git a/apps/Makefile b/apps/Makefile
index f0de58e25..d3078d069 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -45,14 +45,14 @@ APPDIR = ${shell pwd}
# action. It is created by the configured appconfig file (a copy of which
# appears in this directory as .config)
# SUBDIRS is the list of all directories containing Makefiles. It is used
-# only for cleaning. namedapp must always be the first in the list. This
+# only for cleaning. builtin must always be the first in the list. This
# list can be extended by the .config file as well.
CONFIGURED_APPS =
-#SUBDIRS = examples graphics interpreters modbus namedapp nshlib netutils system
-ALL_SUBDIRS = $(dir $(shell /usr/bin/find . -name Makefile))
-SUBDIRS = namedapp/ $(filter-out ./ ./namedapp/ ./examples/,$(ALL_SUBDIRS))
+SUBDIRS = examples interpreters builtin nshlib system
+
+#SUBDIRS = examples graphics interpreters modbus builtin nshlib netutils system
# There are two different mechanisms for obtaining the list of configured
# directories:
@@ -73,20 +73,20 @@ SUBDIRS = namedapp/ $(filter-out ./ ./namedapp/ ./examples/,$(ALL_SUBDIRS))
ifeq ($(CONFIG_NUTTX_NEWCONFIG),y)
-# namedapp/Make.defs must be included first
+# builtin/Make.defs must be included first
--include namedapp/Make.defs
--include examples/Make.defs
--include graphics/Make.defs
--include interpreters/Make.defs
--include modbus/Make.defs
--include netutils/Make.defs
--include nshlib/Make.defs
--include system/Make.defs
+include builtin/Make.defs
+include examples/Make.defs
+include graphics/Make.defs
+include interpreters/Make.defs
+include modbus/Make.defs
+include netutils/Make.defs
+include nshlib/Make.defs
+include system/Make.defs
# INSTALLED_APPS is the list of currently available application directories. It
# is the same as CONFIGURED_APPS, but filtered to exclude any non-existent
-# application directory. namedapp is always in the list of applications to be
+# application directory. builtin is always in the list of applications to be
# built.
INSTALLED_APPS =
@@ -98,10 +98,10 @@ else
# INSTALLED_APPS is the list of currently available application directories. It
# is the same as CONFIGURED_APPS, but filtered to exclude any non-existent
-# application directory. namedapp is always in the list of applications to be
+# application directory. builtin is always in the list of applications to be
# built.
-INSTALLED_APPS = namedapp
+INSTALLED_APPS = builtin
endif
# Create the list of available applications (INSTALLED_APPS)
@@ -139,21 +139,16 @@ $(INSTALLED_APPS):
$(BIN): $(INSTALLED_APPS)
-.context:
+context:
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
$(Q) for %%G in ($(INSTALLED_APPS)) do ( \
- if exist %%G\.context del /f /q %%G\.context \
$(MAKE) -C %%G TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" context \
)
else
$(Q) for dir in $(INSTALLED_APPS) ; do \
- rm -f $$dir/.context ; \
$(MAKE) -C $$dir TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" context ; \
done
endif
- $(Q) touch $@
-
-context: .context
.depend: context Makefile $(SRCS)
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
@@ -184,13 +179,12 @@ endif
$(call DELFILE, $(BIN))
$(call CLEAN)
-distclean: # clean
+distclean:
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
$(Q) for %%G in ($(SUBDIRS)) do ( \
$(MAKE) -C %%G distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" \
)
$(call DELFILE, .config)
- $(call DELFILE, .context)
$(call DELFILE, .depend)
$(Q) ( if exist external ( \
echo ********************************************************" \
@@ -202,7 +196,6 @@ else
$(MAKE) -C $$dir distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"; \
done
$(call DELFILE, .config)
- $(call DELFILE, .context)
$(call DELFILE, .depend)
$(Q) ( if [ -e external ]; then \
echo "********************************************************"; \
diff --git a/apps/README.txt b/apps/README.txt
index 7a379254e..55accfcf6 100644
--- a/apps/README.txt
+++ b/apps/README.txt
@@ -6,26 +6,25 @@ Contents
General
Directory Location
- Named Applications
- Named Startup main() function
+ Built-In Applications
NuttShell (NSH) Built-In Commands
Synchronous Built-In Commands
Application Configuration File
- Example Named Application
+ Example Built-In Application
Building NuttX with Board-Specific Pieces Outside the Source Tree
General
-------
This folder provides various applications found in sub-directories. These
-applications are not inherently a part of NuttX but are provided you help
+applications are not inherently a part of NuttX but are provided to help
you develop your own applications. The apps/ directory is a "break away"
-part of the configuration that you may chose to use or not.
+part of the configuration that you may choose to use or not.
Directory Location
------------------
The default application directory used by the NuttX build should be named
apps/ (or apps-x.y/ where x.y is the NuttX version number). This apps/
-directoy should appear in the directory tree at the same level as the
+directory should appear in the directory tree at the same level as the
NuttX directory. Like:
.
@@ -47,14 +46,14 @@ ways to do that:
path to the application directory on the configuration command line
like: ./configure.sh -a <app-dir> <board-name>/<config-name>
-Named Applications
-------------------
+Built-In Applications
+---------------------
NuttX also supports applications that can be started using a name string.
In this case, application entry points with their requirements are gathered
together in two files:
- - namedapp/namedapp_proto.h Entry points, prototype function
- - namedapp/namedapp_list.h Application specific information and requirements
+ - builtin/builtin_proto.h Entry points, prototype function
+ - builtin/builtin_list.h Application specific information and requirements
The build occurs in several phases as different build targets are executed:
(1) context, (2) depend, and (3) default (all). Application information is
@@ -62,18 +61,18 @@ collected during the make context build phase.
To execute an application function:
- exec_namedapp() is defined in the nuttx/include/apps/apps.h
+ exec_builtin() is defined in the nuttx/include/apps/builtin.h
NuttShell (NSH) Built-In Commands
---------------------------------
-One use of named applications is to provide a way of invoking your custom
+One use of builtin applications is to provide a way of invoking your custom
application through the NuttShell (NSH) command line. NSH will support
a seamless method invoking the applications, when the following option is
enabled in the NuttX configuration file:
CONFIG_NSH_BUILTIN_APPS=y
-Applications registered in the apps/namedapp/namedapp_list.h file will then
+Applications registered in the apps/builtin/builtin_list.h file will then
be accessible from the NSH command line. If you type 'help' at the NSH
prompt, you will see a list of the registered commands.
@@ -96,11 +95,11 @@ after the NSH command.
Application Configuration File
------------------------------
-A special configuration file is used to configure which applications
-are to be included in the build. The source for this file is
-configs/<board>/<configuration>/appconfig. The existence of the appconfig
-file in the board configuration directory is sufficient to enable building
-of applications.
+The old-style NuttX configuration uses a special configuration file is
+used to configure which applications are to be included in the build.
+The source for this file is configs/<board>/<configuration>/appconfig.
+The existence of the appconfig file in the board configuration directory\
+is sufficient to enable building of applications.
The appconfig file is copied into the apps/ directory as .config when
NuttX is configured. .config is included in the toplevel apps/Makefile.
@@ -109,38 +108,101 @@ CONFIGURED_APPS list like:
CONFIGURED_APPS += examples/hello system/poweroff
-Named Start-Up main() function
-------------------------------
-A named application can even be used as the main, start-up entry point
-into your embedded software. When the user defines this option in
-the NuttX configuration file:
+The new NuttX configuration uses kconfig-frontends tools and only the
+NuttX .config file. The new configuration is indicated by the existence
+of the definition CONFIG_NUTTX_NEWCONFIG=y in the NuttX .config file.
+If CONFIG_NUTTX_NEWCONFIG is defined, then the Makefile will:
+
+- Assume that there is no apps/.config file and will instead
+- Include Make.defs files from each of the subdirectories.
+
+When an application is enabled using the kconfig-frontends tool, then
+a new definition is added to the NuttX .config file. For example, if
+you want to enable apps/examples/hello then the old apps/.config would
+have had:
+
+ CONFIGURED_APPS += examples/hello
+
+But in the new configuration there will be no apps/.config file and,
+instead, the NuttX .config will have:
+
+ CONFIG_EXAMPLES_HELLO=y
- CONFIG_BUILTIN_APP_START=<application name>
-
-that application shall be invoked immediately after system starts
-*instead* of the default "user_start" entry point.
-Note that <application name> must be provided as: "hello",
-will call:
+This will select the apps/examples/hello in the following way:
- int hello_main(int argc, char *argv[])
+- The top-level make will include examples/Make.defs
+- examples/Make.defs will set CONFIGURED_APPS += examples/hello
+ like this:
-Example Named Application
--------------------------
+ ifeq ($(CONFIG_EXAMPLES_HELLO),y)
+ CONFIGURED_APPS += examples/hello
+ endif
+
+Thus accomplishing the same thing with no apps/.config file.
+
+Example Built-In Application
+----------------------------
An example application skeleton can be found under the examples/hello
-sub-directory. This example shows how a named application can be added
+sub-directory. This example shows how a builtin application can be added
to the project. One must define:
- 1. create sub-directory as: appname
- 2. provide entry point: appname_main()
- 3. set the requirements in the file: Makefile, specially the lines:
+Old configuration method:
+
+ 1. Create sub-directory as: appname
+
+ 2. In this directory there should be:
+
+ - A Makefile, and
+ - The application source code.
+
+ 3. The application source code should provide the entry point:
+ appname_main()
+
+ 4. Set the requirements in the file: Makefile, specially the lines:
+
+ APPNAME = appname
+ PRIORITY = SCHED_PRIORITY_DEFAULT
+ STACKSIZE = 768
+ ASRCS = asm source file list as a.asm b.asm ...
+ CSRCS = C source file list as foo1.c foo2.c ..
+
+ Look at some of the other Makefiles for examples. Note the
+ special registration logic needed for the context: target
+
+ 5. Add the to the application to the CONFIGIURED_APPS in the
+ apps/.config file:
+
+ CONFIGURED_APPS += appname
+
+New Configuration Method:
+
+ 1. Create sub-directory as: appname
+
+ 2. In this directory there should be:
+
+ - A Make.defs file that would be included by the apps/Makefile
+ - A Kconfig file that would be used by the configuration tool (see
+ misc/tools/kconfig-language.txt). This Kconfig file should be
+ included by the apps/Kconfig file
+ - A Makefile, and
+ - The application source code.
+
+ 3. The application source code should provide the entry point:
+ appname_main()
+
+ 4. Set the requirements in the file: Makefile, specially the lines:
+
+ APPNAME = appname
+ PRIORITY = SCHED_PRIORITY_DEFAULT
+ STACKSIZE = 768
+ ASRCS = asm source file list as a.asm b.asm ...
+ CSRCS = C source file list as foo1.c foo2.c ..
- APPNAME = appname
- PRIORITY = SCHED_PRIORITY_DEFAULT
- STACKSIZE = 768
- ASRCS = asm source file list as a.asm b.asm ...
- CSRCS = C source file list as foo1.c foo2.c ..
+ 4b. The Make.defs file should include a line like:
- 4. add application in the apps/.config
+ ifeq ($(CONFIG_APPNAME),y)
+ CONFIGURED_APPS += appname
+ endif
Building NuttX with Board-Specific Pieces Outside the Source Tree
-----------------------------------------------------------------
diff --git a/apps/builtin/Kconfig b/apps/builtin/Kconfig
new file mode 100644
index 000000000..c3371d708
--- /dev/null
+++ b/apps/builtin/Kconfig
@@ -0,0 +1,17 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+if BUILTIN
+
+config BUILTIN_PROXY_STACKSIZE
+ int "Builtin Proxy Stack Size"
+ default 1024
+ ---help---
+ If exec_builtin uses I/O redirection options, then it will require
+ an intermediary/proxy task to muck with the file descriptors. This
+ configuration item specifies the stack size used for the proxy. Default:
+ 1024 bytes.
+
+endif
diff --git a/apps/namedapp/Make.defs b/apps/builtin/Make.defs
index 399fefee8..ab6292cc3 100644
--- a/apps/namedapp/Make.defs
+++ b/apps/builtin/Make.defs
@@ -1,5 +1,5 @@
############################################################################
-# apps/namedapps/Make.defs
+# apps/builtin/Make.defs
# Adds selected applications to apps/ build
#
# Copyright (C) 2012 Gregory Nutt. All rights reserved.
@@ -34,7 +34,7 @@
#
############################################################################
-ifeq ($(CONFIG_NAMEDAPP),y)
-CONFIGURED_APPS += namedapp
+ifeq ($(CONFIG_BUILTIN),y)
+CONFIGURED_APPS += builtin
endif
diff --git a/apps/namedapp/Makefile b/apps/builtin/Makefile
index a88c73567..d77054f41 100644
--- a/apps/namedapp/Makefile
+++ b/apps/builtin/Makefile
@@ -1,5 +1,5 @@
############################################################################
-# apps/nshlib/Makefile
+# apps/builtin/Makefile
#
# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
@@ -33,20 +33,13 @@
#
############################################################################
--include $(TOPDIR)/.config
-include $(TOPDIR)/Make.defs
include $(APPDIR)/Make.defs
-# NSH Library
-
# Source and object files
ASRCS =
-CSRCS = namedapp.c exec_namedapp.c
-
-ifeq ($(CONFIG_APPS_BINDIR),y)
-CSRCS += binfs.c
-endif
+CSRCS = builtin.c exec_builtin.c
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
@@ -70,7 +63,7 @@ VPATH =
# Build Targets
all: .built
-.PHONY: .context context depend clean distclean
+.PHONY: context depend clean distclean
$(AOBJS): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
@@ -78,33 +71,60 @@ $(AOBJS): %$(OBJEXT): %.S
$(COBJS): %$(OBJEXT): %.c
$(call COMPILE, $<, $@)
-.built: $(OBJS)
+registry$(DELIM).updated:
+ $(V) $(MAKE) -C registry .updated TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
+
+builtin_list.h: registry$(DELIM).updated
+ $(call DELFILE, builtin_list.h)
+ $(Q) touch builtin_list.h
+ifeq ($(CONFIG_WINDOWS_NATIVE),y)
+ $(Q) for /f %%G in ('dir /b registry\*.bdat`) do ( type registry\%%G >> builtin_list.h )
+else
+ $(Q) ( \
+ filelist=`ls registry/*.bdat 2>/dev/null || echo ""`; \
+ for file in $$filelist; \
+ do cat $$file >> builtin_list.h; \
+ done; \
+ )
+endif
+
+builtin_proto.h: registry$(DELIM).updated
+ $(call DELFILE, builtin_proto.h)
+ $(Q) touch builtin_proto.h
+ifeq ($(CONFIG_WINDOWS_NATIVE),y)
+ $(Q) for /f %%G in ('dir /b registry\*.pdat`) do ( type registry\%%G >> builtin_proto.h )
+else
+ $(Q) ( \
+ filelist=`ls registry/*.pdat 2>/dev/null || echo ""`; \
+ for file in $$filelist; \
+ do cat $$file >> builtin_proto.h; \
+ done; \
+ )
+endif
+
+.built: builtin_list.h builtin_proto.h $(OBJS)
$(call ARCHIVE, $(BIN), $(OBJS))
$(Q) touch .built
-.context:
- @echo "/* List of application requirements, generated during make context. */" > namedapp_list.h
- @echo "/* List of application entry points, generated during make context. */" > namedapp_proto.h
- $(Q) touch $@
-
-context: .context
+context:
+ $(Q) $(MAKE) -C registry context TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
-.depend: Makefile $(SRCS)
+.depend: Makefile $(SRCS) builtin_list.h builtin_proto.h
$(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
$(Q) touch $@
depend: .depend
clean:
+ $(Q) $(MAKE) -C registry clean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
$(call DELFILE, .built)
$(call CLEAN)
distclean: clean
- $(call DELFILE, .context)
+ $(Q) $(MAKE) -C registry distclean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)
- $(call DELFILE, namedapp_list.h)
- $(call DELFILE, namedapp_proto.h)
+ $(call DELFILE, builtin_list.h)
+ $(call DELFILE, builtin_proto.h)
-include Make.dep
-
diff --git a/apps/namedapp/namedapp.c b/apps/builtin/builtin.c
index d59ce6e3b..7655a531d 100644
--- a/apps/namedapp/namedapp.c
+++ b/apps/builtin/builtin.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * apps/namedaps/namedapp.c
+ * apps/builtin/builtin.c
*
* Copyright (C) 2011 Uros Platise. All rights reserved.
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
@@ -40,7 +40,8 @@
****************************************************************************/
#include <nuttx/config.h>
-#include <apps/apps.h>
+
+#include <nuttx/binfmt/builtin.h>
/****************************************************************************
* Private Types
@@ -62,11 +63,11 @@ extern "C" {
#define EXTERN extern
#endif
-#include "namedapp_proto.h"
+#include "builtin_proto.h"
-const struct namedapp_s namedapps[] =
+const struct builtin_s g_builtins[] =
{
-# include "namedapp_list.h"
+# include "builtin_list.h"
{ NULL, 0, 0, 0 }
};
@@ -88,9 +89,9 @@ const struct namedapp_s namedapps[] =
* Public Functions
****************************************************************************/
-int number_namedapps(void)
+int number_builtins(void)
{
- return sizeof(namedapps)/sizeof(struct namedapp_s) - 1;
+ return sizeof(g_builtins)/sizeof(struct builtin_s) - 1;
}
diff --git a/apps/builtin/exec_builtin.c b/apps/builtin/exec_builtin.c
new file mode 100644
index 000000000..9fde813d6
--- /dev/null
+++ b/apps/builtin/exec_builtin.c
@@ -0,0 +1,423 @@
+/****************************************************************************
+ * apps/builtin/exec_builtin.c
+ *
+ * Originally by:
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
+ * Author: Uros Platise <uros.platise@isotel.eu>
+ *
+ * With subsequent updates, modifications, and general maintenance by:
+ *
+ * Copyright (C) 2012-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 <string.h>
+#include <fcntl.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/binfmt/builtin.h>
+#include <apps/builtin.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_BUILTIN_PROXY_STACKSIZE
+# define CONFIG_BUILTIN_PROXY_STACKSIZE 1024
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct builtin_parms_s
+{
+ /* Input values */
+
+ FAR const char *redirfile;
+ FAR const char **argv;
+ int oflags;
+ int index;
+
+ /* Returned values */
+
+ pid_t result;
+ int errcode;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static sem_t g_builtin_parmsem = SEM_INITIALIZER(1);
+static sem_t g_builtin_execsem = SEM_INITIALIZER(0);
+static struct builtin_parms_s g_builtin_parms;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bultin_semtake and builtin_semgive
+ *
+ * Description:
+ * Give and take semaphores
+ *
+ * Input Parameters:
+ *
+ * sem - The semaphore to act on.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void bultin_semtake(FAR sem_t *sem)
+{
+ int ret;
+
+ do
+ {
+ ret = sem_wait(sem);
+ ASSERT(ret == 0 || errno == EINTR);
+ }
+ while (ret != 0);
+}
+
+#define builtin_semgive(sem) sem_post(sem)
+
+/****************************************************************************
+ * Name: builtin_taskcreate
+ *
+ * Description:
+ * Execute the builtin task
+ *
+ * Returned Value:
+ * On success, the task ID of the builtin task is returned; On failure, -1
+ * (ERROR) is returned and the errno is set appropriately.
+ *
+ ****************************************************************************/
+
+static int builtin_taskcreate(int index, FAR const char **argv)
+{
+ int ret;
+
+ /* Disable pre-emption. This means that although we start the builtin
+ * application here, it will not actually run until pre-emption is
+ * re-enabled below.
+ */
+
+ sched_lock();
+
+ /* Start the builtin application task */
+
+ ret = TASK_CREATE(g_builtins[index].name, g_builtins[index].priority,
+ g_builtins[index].stacksize, g_builtins[index].main,
+ (argv) ? &argv[1] : (FAR const char **)NULL);
+
+ /* 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
+ if (ret > 0)
+ {
+ struct sched_param param;
+
+ /* Pre-emption is disabled so the task creation and the
+ * following operation will be atomic. The priority of the
+ * new task cannot yet have changed from its initial value.
+ */
+
+ param.sched_priority = g_builtins[index].priority;
+ (void)sched_setscheduler(ret, SCHED_RR, &param);
+ }
+#endif
+
+ /* Now let the builtin application run */
+
+ sched_unlock();
+
+ /* Return the task ID of the new task if the task was sucessfully
+ * started. Otherwise, ret will be ERROR (and the errno value will
+ * be set appropriately).
+ */
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: builtin_proxy
+ *
+ * Description:
+ * Perform output redirection, then execute the builtin task.
+ *
+ * Input Parameters:
+ * Standard task start-up parameters
+ *
+ * Returned Value:
+ * Standard task return value.
+ *
+ ****************************************************************************/
+
+static int builtin_proxy(int argc, char *argv[])
+{
+ int fd;
+ int ret = ERROR;
+
+ /* Open the output file for redirection */
+
+ svdbg("Open'ing redirfile=%s oflags=%04x mode=0644\n",
+ g_builtin_parms.redirfile, g_builtin_parms.oflags);
+
+ fd = open(g_builtin_parms.redirfile, g_builtin_parms.oflags, 0644);
+ if (fd < 0)
+ {
+ /* Remember the errno value. ret is already set to ERROR */
+
+ g_builtin_parms.errcode = errno;
+ sdbg("ERROR: open of %s failed: %d\n",
+ g_builtin_parms.redirfile, g_builtin_parms.errcode);
+ }
+
+ /* Does the return file descriptor happen to match the required file
+ * desciptor number?
+ */
+
+ else if (fd != 1)
+ {
+ /* No.. dup2 to get the correct file number */
+
+ svdbg("Dup'ing %d->1\n", fd);
+
+ ret = dup2(fd, 1);
+ if (ret < 0)
+ {
+ g_builtin_parms.errcode = errno;
+ sdbg("ERROR: dup2 failed: %d\n", g_builtin_parms.errcode);
+ }
+
+ svdbg("Closing fd=%d\n", fd);
+ close(fd);
+ }
+
+ /* Was the setup successful? */
+
+ if (ret == OK)
+ {
+ /* Yes.. Start the task. On success, the task ID of the builtin task
+ * is returned; On failure, -1 (ERROR) is returned and the errno
+ * is set appropriately.
+ */
+
+ ret = builtin_taskcreate(g_builtin_parms.index, g_builtin_parms.argv);
+ if (ret < 0)
+ {
+ g_builtin_parms.errcode = errno;
+ sdbg("ERROR: builtin_taskcreate failed: %d\n",
+ g_builtin_parms.errcode);
+ }
+ }
+
+ /* Post the semaphore to inform the parent task that we have completed
+ * what we need to do.
+ */
+
+ g_builtin_parms.result = ret;
+ builtin_semgive(&g_builtin_execsem);
+ return 0;
+}
+
+/****************************************************************************
+ * Name: builtin_startproxy
+ *
+ * Description:
+ * Perform output redirection, then execute the builtin task.
+ *
+ * Input Parameters:
+ * Standard task start-up parameters
+ *
+ * Returned Value:
+ * On success, the task ID of the builtin task is returned; On failure, -1
+ * (ERROR) is returned and the errno is set appropriately.
+ *
+ ****************************************************************************/
+
+static inline int builtin_startproxy(int index, FAR const char **argv,
+ FAR const char *redirfile, int oflags)
+{
+ struct sched_param param;
+ pid_t proxy;
+ int errcode;
+ int ret;
+
+// DEBUGASSERT(path);
+
+ svdbg("index=%d argv=%p redirfile=%s oflags=%04x\n",
+ index, argv, redirfile, oflags);
+
+ /* We will have to go through an intermediary/proxy task in order to
+ * perform the I/O redirection. This would be a natural place to fork().
+ * However, true fork() behavior requires an MMU and most implementations
+ * of vfork() are not capable of these operations.
+ *
+ * Even without fork(), we can still do the job, but parameter passing is
+ * messier. Unfortunately, there is no (clean) way to pass binary values
+ * as a task parameter, so we will use a semaphore-protected global
+ * structure.
+ */
+
+ /* Get exclusive access to the global parameter structure */
+
+ bultin_semtake(&g_builtin_parmsem);
+
+ /* Populate the parameter structure */
+
+ g_builtin_parms.redirfile = redirfile;
+ g_builtin_parms.argv = argv;
+ g_builtin_parms.result = ERROR;
+ g_builtin_parms.oflags = oflags;
+ g_builtin_parms.index = index;
+
+ /* Get the priority of this (parent) task */
+
+ ret = sched_getparam(0, &param);
+ if (ret < 0)
+ {
+ errcode = errno;
+ sdbg("ERROR: sched_getparam failed: %d\n", errcode);
+ goto errout;
+ }
+
+ /* Start the intermediary/proxy task at the same priority as the parent task. */
+
+ proxy = TASK_CREATE("builtin_proxy", param.sched_priority,
+ CONFIG_BUILTIN_PROXY_STACKSIZE, (main_t)builtin_proxy,
+ (FAR const char **)NULL);
+ if (proxy < 0)
+ {
+ errcode = errno;
+ sdbg("ERROR: Failed to start builtin_proxy: %d\n", errcode);
+ goto errout;
+ }
+
+ /* Wait for the proxy to complete its job. We could use waitpid()
+ * for this.
+ */
+
+ bultin_semtake(&g_builtin_execsem);
+
+ /* Get the result and relinquish our access to the parameter structure */
+
+ set_errno(g_builtin_parms.errcode);
+ builtin_semgive(&g_builtin_parmsem);
+ return g_builtin_parms.result;
+
+errout:
+ set_errno(errcode);
+ builtin_semgive(&g_builtin_parmsem);
+ return ERROR;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: exec_builtin
+ *
+ * Description:
+ * Executes builtin applications registered during 'make context' time.
+ * New application is run in a separate task context (and thread).
+ *
+ * Input Parameter:
+ * filename - Name of the linked-in binary to be started.
+ * argv - Argument list
+ * redirfile - If output if redirected, this parameter will be non-NULL
+ * and will provide the full path to the file.
+ * oflags - If output is redirected, this parameter will provide the
+ * open flags to use. This will support file replacement
+ * of appending to an existing file.
+ *
+ * Returned Value:
+ * This is an end-user function, so it follows the normal convention:
+ * Returns the PID of the exec'ed module. On failure, it.returns
+ * -1 (ERROR) and sets errno appropriately.
+ *
+ ****************************************************************************/
+
+int exec_builtin(FAR const char *appname, FAR const char **argv,
+ FAR const char *redirfile, int oflags)
+{
+ int index;
+ int ret = ERROR;
+
+ /* Verify that an application with this name exists */
+
+ index = builtin_isavail(appname);
+ if (index >= 0)
+ {
+ /* Is output being redirected? */
+
+ if (redirfile)
+ {
+ ret = builtin_startproxy(index, argv, redirfile, oflags);
+ }
+ else
+ {
+ /* Start the builtin application task */
+
+ ret = builtin_taskcreate(index, argv);
+ }
+ }
+
+
+ /* Return the task ID of the new task if the task was sucessfully
+ * started. Otherwise, ret will be ERROR (and the errno value will
+ * be set appropriately).
+ */
+
+ return ret;
+}
diff --git a/apps/builtin/registry/Makefile b/apps/builtin/registry/Makefile
new file mode 100644
index 000000000..4ecd5da9f
--- /dev/null
+++ b/apps/builtin/registry/Makefile
@@ -0,0 +1,61 @@
+############################################################################
+# apps/builtin/registry/Makefile
+#
+# 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.
+#
+############################################################################
+
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# NSH Library
+
+all:
+.PHONY: context depend clean distclean
+
+.updated: $(DEPCONFIG)
+ $(call DELFILE, *.bdat)
+ $(call DELFILE, *.pdat)
+ $(Q) touch .updated
+
+# This must run before any other context target
+
+context: .updated
+
+depend:
+
+clean:
+ $(call CLEAN)
+
+distclean: clean
+ $(call DELFILE, *.bdat)
+ $(call DELFILE, *.pdat)
+ $(call DELFILE, .updated)
diff --git a/apps/examples/Kconfig b/apps/examples/Kconfig
index ae5f0a61a..ec0a97dd4 100644
--- a/apps/examples/Kconfig
+++ b/apps/examples/Kconfig
@@ -39,6 +39,7 @@ source "$APPSDIR/examples/pashello/Kconfig"
source "$APPSDIR/examples/pipe/Kconfig"
source "$APPSDIR/examples/poll/Kconfig"
source "$APPSDIR/examples/pwm/Kconfig"
+source "$APPSDIR/examples/posix_spawn/Kconfig"
source "$APPSDIR/examples/qencoder/Kconfig"
source "$APPSDIR/examples/relays/Kconfig"
source "$APPSDIR/examples/rgmp/Kconfig"
@@ -58,5 +59,4 @@ source "$APPSDIR/examples/usbterm/Kconfig"
source "$APPSDIR/examples/watchdog/Kconfig"
source "$APPSDIR/examples/wget/Kconfig"
source "$APPSDIR/examples/wgetjson/Kconfig"
-source "$APPSDIR/examples/wlan/Kconfig"
source "$APPSDIR/examples/xmlrpc/Kconfig"
diff --git a/apps/examples/Make.defs b/apps/examples/Make.defs
index 91f1331df..68d4d4340 100644
--- a/apps/examples/Make.defs
+++ b/apps/examples/Make.defs
@@ -182,6 +182,10 @@ ifeq ($(CONFIG_EXAMPLES_PWM),y)
CONFIGURED_APPS += examples/pwm
endif
+ifeq ($(CONFIG_EXAMPLES_POSIXSPAWN),y)
+CONFIGURED_APPS += examples/posix_spawn
+endif
+
ifeq ($(CONFIG_EXAMPLES_QENCODER),y)
CONFIGURED_APPS += examples/qencoder
endif
@@ -254,10 +258,6 @@ ifeq ($(CONFIG_EXAMPLES_WGETJSON),y)
CONFIGURED_APPS += examples/wgetjson
endif
-ifeq ($(CONFIG_EXAMPLES_WLAN),y)
-CONFIGURED_APPS += examples/wlan
-endif
-
ifeq ($(CONFIG_EXAMPLES_XMLRPC),y)
CONFIGURED_APPS += examples/xmlrpc
endif
diff --git a/apps/examples/Makefile b/apps/examples/Makefile
index bdbfd4de8..201be955b 100644
--- a/apps/examples/Makefile
+++ b/apps/examples/Makefile
@@ -37,12 +37,15 @@
# Sub-directories
-SUBDIRS = adc buttons can cdcacm composite cxxtest dhcpd discover elf ftpc
-SUBDIRS += ftpd hello helloxx hidkbd igmp json keypadtest lcdrw mm modbus mount
-SUBDIRS += nettest nsh null nx nxconsole nxffs nxflat nxhello nximage
-SUBDIRS += nxlines nxtext ostest pashello pipe poll pwm qencoder relays
-SUBDIRS += rgmp romfs serloop telnetd thttpd tiff touchscreen udp uip
-SUBDIRS += usbserial sendmail usbstorage usbterm watchdog wget wgetjson wlan
+SUBDIRS = adc can cdcacm nsh
+SUBDIRS += math_demo control_demo kalman_demo px4_deamon_app
+
+#SUBDIRS = adc buttons can cdcacm composite cxxtest dhcpd discover elf ftpc
+#SUBDIRS += ftpd hello helloxx hidkbd igmp json keypadtest lcdrw mm modbus mount
+#SUBDIRS += nettest nsh null nx nxconsole nxffs nxflat nxhello nximage
+#SUBDIRS += nxlines nxtext ostest pashello pipe poll pwm posix_spawn qencoder
+#SUBDIRS += relays rgmp romfs serloop telnetd thttpd tiff touchscreen udp uip
+#SUBDIRS += usbserial sendmail usbstorage usbterm watchdog wget wgetjson
# Sub-directories that might need context setup. Directories may need
# context setup for a variety of reasons, but the most common is because
@@ -57,13 +60,14 @@ SUBDIRS += usbserial sendmail usbstorage usbterm watchdog wget wgetjson wlan
CNTXTDIRS = pwm
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
-CNTXTDIRS += adc can cdcacm composite cxxtest dhcpd discover ftpd json keypadtest
-CNTXTDIRS += modbus nettest nxlines relays qencoder telnetd watchdog wgetjson
-endif
-ifeq ($(CONFIG_EXAMPLES_HELLO_BUILTIN),y)
-CNTXTDIRS += hello
+CNTXTDIRS += adc can cdcacm
+
+#CNTXTDIRS += adc can cdcacm composite cxxtest dhcpd discover ftpd hello json
+#CNTXTDIRS += keypadtestmodbus nettest nxlines relays qencoder telnetd watchdog
+#CNTXTDIRS += wgetjson
endif
+
ifeq ($(CONFIG_EXAMPLES_HELLOXX_BUILTIN),y)
CNTXTDIRS += helloxx
endif
@@ -120,7 +124,7 @@ depend: $(foreach SDIR, $(SUBDIRS), $(SDIR)_depend)
clean: $(foreach SDIR, $(SUBDIRS), $(SDIR)_clean)
-distclean: clean $(foreach SDIR, $(SUBDIRS), $(SDIR)_distclean)
+distclean: $(foreach SDIR, $(SUBDIRS), $(SDIR)_distclean)
-include Make.dep
diff --git a/apps/examples/README.txt b/apps/examples/README.txt
index e40a63be9..5996cbb70 100644
--- a/apps/examples/README.txt
+++ b/apps/examples/README.txt
@@ -329,10 +329,10 @@ examples/elf
each program in the ROMFS file system is executed. Requires CONFIG_ELF.
Other configuration options:
- CONFIG_EXAMPLES_ELF_DEVMINOR - The minor device number of the ROMFS block.
- For example, the N in /dev/ramN. Used for registering the RAM block driver
- that will hold the ROMFS file system containing the ELF executables to be
- tested. Default: 0
+ CONFIG_EXAMPLES_ELF_DEVMINOR - The minor device number of the ROMFS block
+ driver. For example, the N in /dev/ramN. Used for registering the RAM
+ block driver that will hold the ROMFS file system containing the ELF
+ executables to be tested. Default: 0
CONFIG_EXAMPLES_ELF_DEVPATH - The path to the ROMFS block driver device. This
must match EXAMPLES_ELF_DEVMINOR. Used for registering the RAM block driver
@@ -348,7 +348,7 @@ examples/elf
Similarly for C++ flags which must be provided in CXXELFFLAGS.
- 2. Your top-level nuttx/Make.defs file must alos include an approproate definition,
+ 2. Your top-level nuttx/Make.defs file must also include an approproate definition,
LDELFFLAGS, to generate a relocatable ELF object. With GNU LD, this should
include '-r' and '-e main' (or _main on some platforms).
@@ -491,7 +491,7 @@ examples/hello
than examples/null with a single printf statement. Really useful only
for bringing up new NuttX architectures.
- * CONFIG_EXAMPLES_HELLO_BUILTIN
+ * CONFIG_NSH_BUILTIN_APPS
Build the "Hello, World" example as an NSH built-in application.
examples/helloxx
@@ -540,9 +540,21 @@ examples/hidkbd
This is a simple test to debug/verify the USB host HID keyboard class
driver.
- CONFIG_EXAMPLES_HIDKBD_DEFPRIO - Priority of "waiter" thread.
- CONFIG_EXAMPLES_HIDKBD_STACKSIZE - Stacksize of "waiter" thread.
-
+ CONFIG_EXAMPLES_HIDKBD_DEFPRIO - Priority of "waiter" thread. Default:
+ 50
+ CONFIG_EXAMPLES_HIDKBD_STACKSIZE - Stacksize of "waiter" thread. Default
+ 1024
+ CONFIG_EXAMPLES_HIDKBD_DEVNAME - Name of keyboard device to be used.
+ Default: "/dev/kbda"
+ CONFIG_EXAMPLES_HIDKBD_ENCODED - Decode special key press events in the
+ user buffer. In this case, the example coded will use the interfaces
+ defined in include/nuttx/input/kbd_codec.h to decode the returned
+ keyboard data. These special keys include such things as up/down
+ arrows, home and end keys, etc. If this not defined, only 7-bit print-
+ able and control ASCII characters will be provided to the user.
+ Requires CONFIG_HIDKBD_ENCODED && CONFIG_LIB_KBDCODEC
+
+endif
examples/igmp
^^^^^^^^^^^^^
@@ -1190,6 +1202,80 @@ examples/poll
CONFIGURED_APPS += uiplib
+examples/posix_spawn
+^^^^^^^^^^^^^^^^^^^^
+
+ This is a simple test of the posix_spawn() API. The example derives from
+ examples/elf. As a result, these tests are built using the relocatable
+ ELF format installed in a ROMFS file system. At run time, the test program
+ in the ROMFS file system is spawned using posix_spawn().
+
+ Requires:
+
+ CONFIG_BINFMT_DISABLE=n - Don't disable the binary loader
+ CONFIG_ELF=y - Enable ELF binary loader
+ CONFIG_LIBC_EXECFUNCS=y - Enable support for posix_spawn
+ CONFIG_EXECFUNCS_SYMTAB="exports" - The name of the symbol table
+ created by the test.
+ CONFIG_EXECFUNCS_NSYMBOLS=10 - Value does not matter, it will be
+ corrected at runtime.
+ CONFIG_POSIX_SPAWN_STACKSIZE=768 - This default setting.
+
+ Test-specific configuration options:
+
+ CONFIG_EXAMPLES_POSIXSPAWN_DEVMINOR - The minor device number of the ROMFS
+ block. driver. For example, the N in /dev/ramN. Used for registering the
+ RAM block driver that will hold the ROMFS file system containing the ELF
+ executables to be tested. Default: 0
+
+ CONFIG_EXAMPLES_POSIXSPAWN_DEVPATH - The path to the ROMFS block driver
+ device. This must match EXAMPLES_POSIXSPAWN_DEVMINOR. Used for
+ registering the RAM block driver that will hold the ROMFS file system
+ containing the ELF executables to be tested. Default: "/dev/ram0"
+
+ NOTES:
+
+ 1. CFLAGS should be provided in CELFFLAGS. RAM and FLASH memory regions
+ may require long allcs. For ARM, this might be:
+
+ CELFFLAGS = $(CFLAGS) -mlong-calls
+
+ Similarly for C++ flags which must be provided in CXXELFFLAGS.
+
+ 2. Your top-level nuttx/Make.defs file must also include an approproate
+ definition, LDELFFLAGS, to generate a relocatable ELF object. With GNU
+ LD, this should include '-r' and '-e main' (or _main on some platforms).
+
+ LDELFFLAGS = -r -e main
+
+ If you use GCC to link, you make also need to include '-nostdlib' or
+ '-nostartfiles' and '-nodefaultlibs'.
+
+ 3. This example also requires genromfs. genromfs can be build as part of the
+ nuttx toolchain. Or can built from the genromfs sources that can be found
+ at misc/tools/genromfs-0.5.2.tar.gz. In any event, the PATH variable must
+ include the path to the genromfs executable.
+
+ 4. ELF size: The ELF files in this example are, be default, quite large
+ because they include a lot of "build garbage". You can greatly reduce the
+ size of the ELF binaries are using the 'objcopy --strip-unneeded' command to
+ remove un-necessary information from the ELF files.
+
+ 5. Simulator. You cannot use this example with the the NuttX simulator on
+ Cygwin. That is because the Cygwin GCC does not generate ELF file but
+ rather some Windows-native binary format.
+
+ If you really want to do this, you can create a NuttX x86 buildroot toolchain
+ and use that be build the ELF executables for the ROMFS file system.
+
+ 6. Linker scripts. You might also want to use a linker scripts to combine
+ sections better. An example linker script is at nuttx/binfmt/libelf/gnu-elf.ld.
+ That example might have to be tuned for your particular linker output to
+ position additional sections correctly. The GNU LD LDELFFLAGS then might
+ be:
+
+ LDELFFLAGS = -r -e main -T$(TOPDIR)/binfmt/libelf/gnu-elf.ld
+
examples/pwm
^^^^^^^^^^^^
diff --git a/apps/examples/adc/Makefile b/apps/examples/adc/Makefile
index 69862b383..3cbe843f6 100644
--- a/apps/examples/adc/Makefile
+++ b/apps/examples/adc/Makefile
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
-.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
- @touch $@
-endif
-context: .context
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
+else
+context:
+endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
diff --git a/apps/examples/buttons/Makefile b/apps/examples/buttons/Makefile
index 77c1cd67d..a2e8679d4 100644
--- a/apps/examples/buttons/Makefile
+++ b/apps/examples/buttons/Makefile
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
-.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
- @touch $@
-endif
-context: .context
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
+else
+context:
+endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
diff --git a/apps/examples/can/Makefile b/apps/examples/can/Makefile
index 8924797e3..548c6702c 100644
--- a/apps/examples/can/Makefile
+++ b/apps/examples/can/Makefile
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
-.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
- @touch $@
-endif
-context: .context
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
+else
+context:
+endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
diff --git a/apps/examples/cdcacm/Makefile b/apps/examples/cdcacm/Makefile
index e8d03807d..2cf3a107f 100644
--- a/apps/examples/cdcacm/Makefile
+++ b/apps/examples/cdcacm/Makefile
@@ -87,12 +87,17 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
-.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME1)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME1),$(PRIORITY1),$(STACKSIZE1),$(APPNAME1)_main)
+
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME2)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME2),$(PRIORITY2),$(STACKSIZE2),$(APPNAME2)_main)
- @touch $@
-context: .context
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME1)_main.bdat $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME2)_main.bdat
+else
+context:
+endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
diff --git a/apps/examples/hello/Makefile b/apps/examples/hello/Makefile
index 560b0da35..c3b9744d7 100644
--- a/apps/examples/hello/Makefile
+++ b/apps/examples/hello/Makefile
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
-.context:
-ifeq ($(CONFIG_EXAMPLES_HELLO_BUILTIN),y)
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
- @touch $@
-endif
-context: .context
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
+else
+context:
+endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
diff --git a/apps/examples/helloxx/Makefile b/apps/examples/helloxx/Makefile
index 062da7d58..44d880658 100644
--- a/apps/examples/helloxx/Makefile
+++ b/apps/examples/helloxx/Makefile
@@ -100,13 +100,14 @@ $(CXXOBJS): %$(OBJEXT): %.cxx
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
-.context:
ifeq ($(CONFIG_EXAMPLES_HELLOXX_BUILTIN),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
- @touch $@
-endif
-context: .context
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
+else
+context:
+endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
diff --git a/apps/examples/ostest/Makefile b/apps/examples/ostest/Makefile
index 3e78c64e8..5a8ff7293 100644
--- a/apps/examples/ostest/Makefile
+++ b/apps/examples/ostest/Makefile
@@ -52,6 +52,10 @@ ifeq ($(CONFIG_ARCH_FPU),y)
CSRCS += fpu.c
endif
+ifeq ($(CONFIG_SCHED_WAITPID),y)
+CSRCS += waitpid.c
+endif
+
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
CSRCS += cancel.c cond.c mutex.c sem.c barrier.c
ifneq ($(CONFIG_RR_INTERVAL),0)
@@ -84,6 +88,10 @@ ifneq ($(CONFIG_DISABLE_POSIX_TIMERS),y)
CSRCS += posixtimer.c
endif
+ifeq ($(CONFIG_ARCH_HAVE_VFORK),y)
+CSRCS += vfork.c
+endif
+
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
ifneq ($(CONFIG_DISABLE_PTHREAD),y)
ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
@@ -127,13 +135,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
-.context:
ifeq ($(CONFIG_EXAMPLES_OSTEST_BUILTIN),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
- @touch $@
-endif
-context: .context
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
+else
+context:
+endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
diff --git a/apps/examples/ostest/ostest.h b/apps/examples/ostest/ostest.h
index a4af37f05..5217f0a0c 100644
--- a/apps/examples/ostest/ostest.h
+++ b/apps/examples/ostest/ostest.h
@@ -105,71 +105,83 @@
/* dev_null.c ***************************************************************/
-extern int dev_null(void);
+int dev_null(void);
/* fpu.c ********************************************************************/
-extern void fpu_test(void);
+void fpu_test(void);
+
+/* waitpid.c ****************************************************************/
+
+#ifdef CONFIG_SCHED_WAITPID
+int waitpid_test(void);
+#endif
/* mutex.c ******************************************************************/
-extern void mutex_test(void);
+void mutex_test(void);
/* rmutex.c ******************************************************************/
-extern void recursive_mutex_test(void);
+void recursive_mutex_test(void);
/* sem.c ********************************************************************/
-extern void sem_test(void);
+void sem_test(void);
/* cond.c *******************************************************************/
-extern void cond_test(void);
+void cond_test(void);
/* mqueue.c *****************************************************************/
-extern void mqueue_test(void);
+void mqueue_test(void);
/* timedmqueue.c ************************************************************/
-extern void timedmqueue_test(void);
+void timedmqueue_test(void);
/* cancel.c *****************************************************************/
-extern void cancel_test(void);
+void cancel_test(void);
/* timedwait.c **************************************************************/
-extern void timedwait_test(void);
+void timedwait_test(void);
/* sighand.c ****************************************************************/
-extern void sighand_test(void);
+void sighand_test(void);
/* posixtimers.c ************************************************************/
-extern void timer_test(void);
+void timer_test(void);
/* roundrobin.c *************************************************************/
-extern void rr_test(void);
+void rr_test(void);
/* barrier.c ****************************************************************/
-extern void barrier_test(void);
+void barrier_test(void);
/* prioinherit.c ************************************************************/
-extern void priority_inheritance(void);
+void priority_inheritance(void);
+
+/* vfork.c ******************************************************************/
+
+#ifdef CONFIG_ARCH_HAVE_VFORK
+int vfork_test(void);
+#endif
/* APIs exported (conditionally) by the OS specifically for testing of
* priority inheritance
*/
#if defined(CONFIG_DEBUG) && defined(CONFIG_PRIORITY_INHERITANCE) && defined(CONFIG_SEM_PHDEBUG)
-extern void sem_enumholders(FAR sem_t *sem);
-extern int sem_nfreeholders(void);
+void sem_enumholders(FAR sem_t *sem);
+int sem_nfreeholders(void);
#else
# define sem_enumholders(sem)
# define sem_nfreeholders()
diff --git a/apps/examples/ostest/ostest_main.c b/apps/examples/ostest/ostest_main.c
index 46726d515..aab1ff045 100644
--- a/apps/examples/ostest/ostest_main.c
+++ b/apps/examples/ostest/ostest_main.c
@@ -301,6 +301,14 @@ static int user_main(int argc, char *argv[])
check_test_memory_usage();
#endif
+#ifdef CONFIG_SCHED_WAITPID
+ /* Check waitpid() and friends */
+
+ printf("\nuser_main: waitpid test\n");
+ waitpid_test();
+ check_test_memory_usage();
+#endif
+
#ifndef CONFIG_DISABLE_PTHREAD
/* Verify pthreads and pthread mutex */
@@ -409,6 +417,11 @@ static int user_main(int argc, char *argv[])
check_test_memory_usage();
#endif /* CONFIG_PRIORITY_INHERITANCE && !CONFIG_DISABLE_SIGNALS && !CONFIG_DISABLE_PTHREAD */
+#ifdef CONFIG_ARCH_HAVE_VFORK
+ printf("\nuser_main: vfork() test\n");
+ vfork_test();
+#endif
+
/* Compare memory usage at time ostest_main started until
* user_main exits. These should not be identical, but should
* be similar enough that we can detect any serious OS memory
@@ -428,6 +441,7 @@ static int user_main(int argc, char *argv[])
show_memory_usage(&g_mmbefore, &g_mmafter);
#endif
}
+
printf("user_main: Exitting\n");
return 0;
}
diff --git a/apps/examples/ostest/sighand.c b/apps/examples/ostest/sighand.c
index eabfe5646..32b182c21 100644
--- a/apps/examples/ostest/sighand.c
+++ b/apps/examples/ostest/sighand.c
@@ -54,12 +54,37 @@ static sem_t sem;
static bool sigreceived = false;
static bool threadexited = false;
+#ifdef CONFIG_SCHED_HAVE_PARENT
+static void death_of_child(int signo, siginfo_t *info, void *ucontext)
+{
+ /* Use of printf in a signal handler is NOT safe! It can cause deadlocks!
+ * Also, signals are not queued by NuttX. As a consequence, some
+ * notifications will get lost (or the info data can be overwrittedn)!
+ * Because POSIX does not require signals to be queued, I do not think
+ * that this is a bug (the overwriting is a bug, however).
+ */
+
+ if (info)
+ {
+ printf("death_of_child: PID %d received signal=%d code=%d pid=%d status=%d\n",
+ getpid(), signo, info->si_code, info->si_pid, info->si_status);
+ }
+ else
+ {
+ printf("death_of_child: PID %d received signal=%d (no info?)\n",
+ getpid(), signo);
+ }
+}
+#endif
+
static void wakeup_action(int signo, siginfo_t *info, void *ucontext)
{
sigset_t oldset;
sigset_t allsigs;
int status;
+ /* Use of printf in a signal handler is NOT safe! It can cause deadlocks! */
+
printf("wakeup_action: Received signal %d\n" , signo);
sigreceived = true;
@@ -186,6 +211,11 @@ static int waiter_main(int argc, char *argv[])
void sighand_test(void)
{
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ struct sigaction act;
+ struct sigaction oact;
+ sigset_t sigset;
+#endif
struct sched_param param;
union sigval sigvalue;
pid_t waiterpid;
@@ -195,6 +225,32 @@ void sighand_test(void)
printf("sighand_test: Initializing semaphore to 0\n" );
sem_init(&sem, 0, 0);
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ printf("sighand_test: Unmasking SIGCHLD\n");
+
+ (void)sigemptyset(&sigset);
+ (void)sigaddset(&sigset, SIGCHLD);
+ status = sigprocmask(SIG_UNBLOCK, &sigset, NULL);
+ if (status != OK)
+ {
+ printf("sighand_test: ERROR sigprocmask failed, status=%d\n",
+ status);
+ }
+
+ printf("sighand_test: Registering SIGCHLD handler\n" );
+ act.sa_sigaction = death_of_child;
+ act.sa_flags = SA_SIGINFO;
+
+ (void)sigfillset(&act.sa_mask);
+ (void)sigdelset(&act.sa_mask, SIGCHLD);
+
+ status = sigaction(SIGCHLD, &act, &oact);
+ if (status != OK)
+ {
+ printf("waiter_main: ERROR sigaction failed, status=%d\n" , status);
+ }
+#endif
+
/* Start waiter thread */
printf("sighand_test: Starting waiter task\n" );
@@ -262,6 +318,13 @@ void sighand_test(void)
printf("sighand_test: ERROR signal handler did not run\n" );
}
+ /* Detach the signal handler */
+
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ act.sa_sigaction = SIG_DFL;
+ status = sigaction(SIGCHLD, &act, &oact);
+#endif
+
printf("sighand_test: done\n" );
FFLUSH();
}
diff --git a/apps/namedapp/namedapp.h b/apps/examples/ostest/vfork.c
index 7fcdf42dc..4e1b8c892 100644
--- a/apps/namedapp/namedapp.h
+++ b/apps/examples/ostest/vfork.c
@@ -1,10 +1,8 @@
/****************************************************************************
- * apps/namedaps/namedapp.h
+ * examples/ostest/vfork.c
*
- * Copyright (C) 2011 Uros Platise. All rights reserved.
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Authors: Uros Platise <uros.platise@isotel.eu>
- * Gregory Nutt <gnutt@nuttx.org>
+ * 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
@@ -35,44 +33,71 @@
*
****************************************************************************/
-#ifndef __APPS_NAMEDAPP_NAMEDAPP_H
-#define __APPS_NAMEDAPP_NAMEDAPP_H
-
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
-#include <apps/apps.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "ostest.h"
/****************************************************************************
- * Public Types
+ * Pre-processor Definitions
****************************************************************************/
/****************************************************************************
- * Public Data
+ * Private Data
****************************************************************************/
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
+#if defined(CONFIG_ARCH_HAVE_VFORK) && !defined(CONFIG_DISABLE_SIGNALS)
+static volatile bool g_vforkchild;
#endif
-EXTERN const struct namedapp_s namedapps[];
-
/****************************************************************************
* Public Functions
****************************************************************************/
-EXTERN int number_namedapps(void);
+int vfork_test(void)
+{
+#if defined(CONFIG_ARCH_HAVE_VFORK) && !defined(CONFIG_DISABLE_SIGNALS)
+ pid_t pid;
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
+ g_vforkchild = false;
+ pid = vfork();
+ if (pid == 0)
+ {
+ /* There is not very much that the child is permitted to do. Perhaps
+ * it can just set g_vforkchild.
+ */
-#endif /* __APPS_NAMEDAPP_NAMEDAPP_H */
+ g_vforkchild = true;
+ exit(0);
+ }
+ else if (pid < 0)
+ {
+ printf("vfork_test: vfork() failed: %d\n", errno);
+ return -1;
+ }
+ else
+ {
+ sleep(1);
+ if (g_vforkchild)
+ {
+ printf("vfork_test: Child %d ran successfully\n", pid);
+ }
+ else
+ {
+ printf("vfork_test: ERROR Child %d did not run\n", pid);
+ return -1;
+ }
+ }
+#endif
+ return 0;
+}
diff --git a/apps/examples/ostest/waitpid.c b/apps/examples/ostest/waitpid.c
new file mode 100644
index 000000000..e53b49213
--- /dev/null
+++ b/apps/examples/ostest/waitpid.c
@@ -0,0 +1,269 @@
+/****************************************************************************
+ * examples/ostest/waitpid.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 <sys/wait.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "ostest.h"
+
+#ifdef CONFIG_SCHED_WAITPID
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define RETURN_STATUS 14
+#define NCHILDREN 3
+#define PRIORITY 100
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static int g_waitpids[NCHILDREN];
+
+/****************************************************************************
+ * Priviate Functions
+ ****************************************************************************/
+
+static int waitpid_main(int argc, char *argv[])
+{
+ pid_t me = getpid();
+
+ printf("waitpid_main: PID %d Started\n", me);
+ sleep(3);
+ printf("waitpid_main: PID %d exitting with result=%d\n", me, RETURN_STATUS);
+ return RETURN_STATUS;
+}
+
+static void waitpid_start_children(void)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < NCHILDREN; i++)
+ {
+ ret = TASK_CREATE("waitpid", PRIORITY, STACKSIZE, waitpid_main, NULL);
+ if (ret < 0)
+ {
+ printf("waitpid_start_child: ERROR Failed to start user_main\n");
+ }
+ else
+ {
+ printf("waitpid_start_child: Started waitpid_main at PID=%d\n", ret);
+ }
+
+ g_waitpids[i] = ret;
+ }
+}
+
+static void waitpid_last(void)
+{
+ int stat_loc;
+ int ret;
+
+ printf("waitpid_last: Waiting for PID=%d with waitpid()\n",
+ g_waitpids[NCHILDREN-1]);
+
+ ret = (int)waitpid(g_waitpids[NCHILDREN-1], &stat_loc, 0);
+ if (ret < 0)
+ {
+ int errcode = errno;
+ printf("waitpid_last: ERROR: PID %d waitpid failed: %d\n",
+ g_waitpids[NCHILDREN-1], errcode);
+ }
+ else if (stat_loc != RETURN_STATUS)
+ {
+ printf("waitpid_last: ERROR: PID %d return status is %d, expected %d\n",
+ g_waitpids[NCHILDREN-1], stat_loc, RETURN_STATUS);
+ }
+ else
+ {
+ printf("waitpid_last: PID %d waitpid succeeded with stat_loc=%d\n",
+ g_waitpids[NCHILDREN-1], stat_loc);
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int waitpid_test(void)
+{
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ siginfo_t info;
+#endif
+ int stat_loc;
+ int ret;
+
+ /* Start the children and wait for first one to complete */
+
+ printf("\nTest waitpid()\n");
+ waitpid_start_children();
+
+ printf("waitpid_test: Waiting for PID=%d with waitpid()\n", g_waitpids[0]);
+ ret = (int)waitpid(g_waitpids[0], &stat_loc, 0);
+ if (ret < 0)
+ {
+ int errcode = errno;
+ printf("waitpid_test: ERROR: PID %d waitpid failed: %d\n",
+ g_waitpids[0], errcode);
+ }
+ else if (ret != g_waitpids[0])
+ {
+ printf("waitpid_test: ERROR: PID %d wait returned PID %d\n",
+ g_waitpids[0], ret);
+ }
+ else if (stat_loc != RETURN_STATUS)
+ {
+ printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
+ g_waitpids[0], stat_loc, RETURN_STATUS);
+ }
+ else
+ {
+ printf("waitpid_test: PID %d waitpid succeeded with stat_loc=%d\n",
+ g_waitpids[0], stat_loc);
+ }
+
+ /* Wait a big to make sure that the other threads complete */
+
+ waitpid_last();
+ sleep(1);
+
+#ifdef CONFIG_SCHED_HAVE_PARENT
+ /* Start the children and wait for first one to complete */
+
+ printf("\nTest waitid(P_PID)\n");
+ waitpid_start_children();
+
+ printf("waitpid_test: Waiting for PID=%d with waitid()\n", g_waitpids[0]);
+ ret = waitid(P_PID, (id_t)g_waitpids[0], &info, WEXITED);
+ if (ret < 0)
+ {
+ int errcode = errno;
+ printf("waitpid_test: ERROR: PID %d waitid failed: %d\n",
+ g_waitpids[0], errcode);
+ }
+ else if (info.si_pid != g_waitpids[0])
+ {
+ printf("waitpid_test: ERROR: PID %d waitid returned PID %d\n",
+ g_waitpids[0], info.si_pid);
+ }
+ else if (info.si_status != RETURN_STATUS)
+ {
+ printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
+ info.si_pid, info.si_status, RETURN_STATUS);
+ }
+ else
+ {
+ printf("waitpid_test: waitid PID %d succeeded with si_status=%d\n",
+ info.si_pid, info.si_status);
+ }
+
+ /* Wait a big to make sure that the other threads complete */
+
+ waitpid_last();
+ sleep(1);
+
+ /* Start the children and wait for any one to complete */
+
+ printf("\nTest waitid(P_ALL)\n");
+ waitpid_start_children();
+
+ printf("waitpid_test: Waiting for any child with waitid()\n");
+ ret = waitid(P_ALL, 0, &info, WEXITED);
+ if (ret < 0)
+ {
+ int errcode = errno;
+ printf("waitpid_test: ERROR: waitid failed: %d\n", errcode);
+ }
+ else if (info.si_status != RETURN_STATUS)
+ {
+ printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
+ info.si_pid, info.si_status, RETURN_STATUS);
+ }
+ else
+ {
+ printf("waitpid_test: PID %d waitid succeeded with si_status=%d\n",
+ info.si_pid, info.si_status);
+ }
+
+ /* Wait a big to make sure that the other threads complete */
+
+ waitpid_last();
+ sleep(1);
+
+ /* Start the children and wait for first one to complete */
+
+ printf("\nTest wait()\n");
+ waitpid_start_children();
+
+ printf("waitpid_test: Waiting for any child with wait()\n");
+ ret = (int)wait(&stat_loc);
+ if (ret < 0)
+ {
+ int errcode = errno;
+ printf("waitpid_test: ERROR: wait failed: %d\n", errcode);
+ }
+ else if (stat_loc != RETURN_STATUS)
+ {
+ printf("waitpid_test: ERROR: PID %d return status is %d, expected %d\n",
+ ret, stat_loc, RETURN_STATUS);
+ }
+ else
+ {
+ printf("waitpid_test: PID %d wait succeeded with stat_loc=%d\n",
+ ret, stat_loc);
+ }
+
+ /* Wait a big to make sure that the other threads complete */
+
+ waitpid_last();
+ sleep(1);
+#endif
+
+ return 0;
+}
+
+#endif /* CONFIG_SCHED_WAITPID */
diff --git a/apps/examples/posix_spawn/Kconfig b/apps/examples/posix_spawn/Kconfig
new file mode 100644
index 000000000..508065913
--- /dev/null
+++ b/apps/examples/posix_spawn/Kconfig
@@ -0,0 +1,29 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+config EXAMPLES_POSIXSPAWN
+ bool "posix_spawn Unit Test"
+ default n
+ ---help---
+ Enable the posix_spawn() unit test
+
+if EXAMPLES_POSIXSPAWN
+config EXAMPLES_POSIXSPAWN_DEVMINOR
+ int "ROMFS Minor Device Number"
+ default 0
+ ---help---
+ The minor device number of the ROMFS block. For example, the N in /dev/ramN.
+ Used for registering the RAM block driver that will hold the ROMFS file system
+ containing the ELF executables to be tested. Default: 0
+
+config EXAMPLES_POSIXSPAWN_DEVPATH
+ string "ROMFS Devie Path"
+ default "/dev/ram0"
+ ---help---
+ The path to the ROMFS block driver device. This must match EXAMPLES_POSIXSPAWN_DEVMINOR.
+ Used for registering the RAM block driver that will hold the ROMFS file system
+ containing the ELF executables to be tested. Default: "/dev/ram0"
+
+endif
diff --git a/apps/examples/posix_spawn/Makefile b/apps/examples/posix_spawn/Makefile
new file mode 100644
index 000000000..0bfa36e55
--- /dev/null
+++ b/apps/examples/posix_spawn/Makefile
@@ -0,0 +1,130 @@
+############################################################################
+# apps/examples/posix_spawn/Makefile
+#
+# 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.
+#
+############################################################################
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# ELF Example
+
+ASRCS =
+CSRCS = spawn_main.c symtab.c
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS)
+OBJS = $(AOBJS) $(COBJS)
+
+ifeq ($(CONFIG_WINDOWS_NATIVE),y)
+ BIN = ..\..\libapps$(LIBEXT)
+else
+ifeq ($(WINTOOL),y)
+ BIN = ..\\..\\libapps$(LIBEXT)
+else
+ BIN = ../../libapps$(LIBEXT)
+endif
+endif
+
+ROOTDEPPATH = --dep-path . --dep-path filesystem
+
+# Build targets
+
+VPATH = filesystem
+
+all: build
+.PHONY: build clean_filesystem clean depend distclean
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+# This is a little messy. The build is broken into two pieces: (1) the
+# filesystem/ subdir build that auto-generates several files, and (2) the library
+# build. This is done because we need a fresh build context after auto-
+# generating the source files.
+
+build_lib: $(OBJS)
+ $(call ARCHIVE, $(BIN), $(OBJS))
+
+build:
+ @$(MAKE) -C filesystem TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV)
+ @$(MAKE) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" build_lib
+
+context:
+
+# We can't make dependencies in this directory because the required
+# header files may not yet exist.
+
+.depend:
+ @touch $@
+
+depend: .depend
+
+clean_filesystem:
+ @$(MAKE) -C filesystem TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV) clean
+
+clean: clean_filesystem
+ $(call CLEAN)
+
+distclean: clean
+ $(call DELFILE, Make.dep)
+ $(call DELFILE, .depend)
+
+# There are no dependencies in this directory. Some of more important
+# and more obvious dependencies are hard-coded here:
+
+spawn_main.o: spawn_main.c \
+ $(TOPDIR)/include/nuttx/config.h \
+ $(TOPDIR)/include/nuttx/compiler.h \
+ $(TOPDIR)/include/sys/mount.h \
+ $(TOPDIR)/include/stdio.h \
+ $(TOPDIR)/include/stdlib.h \
+ $(TOPDIR)/include/unistd.h \
+ $(TOPDIR)/include/string.h \
+ $(TOPDIR)/include/fcntl.h \
+ $(TOPDIR)/include/spawn.h \
+ $(TOPDIR)/include/debug.h \
+ $(TOPDIR)/include/errno.h \
+ $(TOPDIR)/include/nuttx/ramdisk.h \
+ $(TOPDIR)/include/nuttx/binfmt/elf.h \
+ $(TOPDIR)/include/nuttx/binfmt/symtab.h \
+ filesystem/romfs.h
+
+symtab.o: filesystem/symtab.c \
+ $(TOPDIR)/include/nuttx/compiler.h \
+ $(TOPDIR)/include/nuttx/binfmt/symtab.h
diff --git a/apps/examples/posix_spawn/filesystem/Makefile b/apps/examples/posix_spawn/filesystem/Makefile
new file mode 100644
index 000000000..26897426c
--- /dev/null
+++ b/apps/examples/posix_spawn/filesystem/Makefile
@@ -0,0 +1,88 @@
+############################################################################
+# apps/examples/posix_spawn/filesystem/Makefile
+#
+# 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.
+#
+############################################################################
+
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)$(DELIM)Make.defs
+
+SPAWN_DIR = $(APPDIR)$(DELIM)examples$(DELIM)posix_spawn
+FILESYSTEM_DIR = $(SPAWN_DIR)$(DELIM)filesystem
+ROMFS_DIR = $(FILESYSTEM_DIR)$(DELIM)romfs
+ROMFS_IMG = $(FILESYSTEM_DIR)$(DELIM)romfs.img
+ROMFS_HDR = $(FILESYSTEM_DIR)$(DELIM)romfs.h
+SYMTAB_SRC = $(FILESYSTEM_DIR)$(DELIM)symtab.c
+
+all: $(ROMFS_HDR) $(SYMTAB_SRC)
+.PHONY: all hello/hello redirect/redirect clean populate
+
+# Create the romfs directory
+
+$(ROMFS_DIR):
+ $(Q) mkdir $(ROMFS_DIR)
+
+# Build the hello test program
+
+hello/hello:
+ $(Q) $(MAKE) -C hello hello TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
+
+# Build the redirection test program
+
+redirect/redirect:
+ $(Q) $(MAKE) -C redirect redirect TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
+
+# Create the romfs.img file from the romfs directory
+
+$(ROMFS_IMG): hello/hello redirect/redirect testdata.txt $(ROMFS_DIR)
+ $(Q) $(MAKE) -C hello install TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
+ $(Q) $(MAKE) -C redirect install TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
+ $(Q) install --mode=0644 testdata.txt $(ROMFS_DIR)/testdata.txt
+ $(Q) genromfs -f $@ -d $(ROMFS_DIR) -V "POSIXSPAWN"
+
+# Create the romfs.h header file from the romfs.img file
+
+$(ROMFS_HDR) : $(ROMFS_IMG)
+ $(Q) (cd $(FILESYSTEM_DIR); xxd -i romfs.img | sed -e "s/^unsigned/static const unsigned/g" >$@)
+
+# Create the exported symbol table
+
+$(SYMTAB_SRC): $(ROMFS_DIR)/hello $(ROMFS_DIR)/redirect $(ROMFS_DIR)/testdata.txt
+ $(Q) $(FILESYSTEM_DIR)$(DELIM)mksymtab.sh $(ROMFS_DIR) >$@
+
+# Clean each subdirectory
+
+clean:
+ $(Q) $(MAKE) -C hello clean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
+ $(Q) $(MAKE) -C redirect clean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
+ $(Q) rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB_SRC)
+ $(Q) rm -rf $(ROMFS_DIR)
diff --git a/apps/examples/posix_spawn/filesystem/hello/hello.c b/apps/examples/posix_spawn/filesystem/hello/hello.c
new file mode 100644
index 000000000..1b269d85f
--- /dev/null
+++ b/apps/examples/posix_spawn/filesystem/hello/hello.c
@@ -0,0 +1,78 @@
+/****************************************************************************
+ * examples/posix_spawn/filesystem/hello/hello.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 <stdio.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, char **argv)
+{
+ int i;
+
+ /* Mandatory "Hello, world!" */
+
+ puts("Getting ready to say \"Hello, world\"\n");
+ printf("Hello, world!\n");
+ puts("It has been said.\n");
+
+ /* Print arguments */
+
+ printf("argc\t= %d\n", argc);
+ printf("argv\t= 0x%p\n", argv);
+
+ for (i = 0; i < argc; i++)
+ {
+ printf("argv[%d]\t= ", i);
+ if (argv[i])
+ {
+ printf("(0x%p) \"%s\"\n", argv[i], argv[i]);
+ }
+ else
+ {
+ printf("NULL?\n");
+ }
+ }
+
+ printf("argv[%d]\t= 0x%p\n", argc, argv[argc]);
+ printf("Goodbye, world!\n");
+ return 0;
+}
diff --git a/apps/examples/posix_spawn/filesystem/mksymtab.sh b/apps/examples/posix_spawn/filesystem/mksymtab.sh
new file mode 100755
index 000000000..51408a89c
--- /dev/null
+++ b/apps/examples/posix_spawn/filesystem/mksymtab.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+
+usage="Usage: $0 <test-dir-path>"
+
+# Check for the required ROMFS directory path
+
+dir=$1
+if [ -z "$dir" ]; then
+ echo "ERROR: Missing <test-dir-path>"
+ echo ""
+ echo $usage
+ exit 1
+fi
+
+if [ ! -d "$dir" ]; then
+ echo "ERROR: Directory $dir does not exist"
+ echo ""
+ echo $usage
+ exit 1
+fi
+
+# Extract all of the undefined symbols from the ELF files and create a
+# list of sorted, unique undefined variable names.
+
+varlist=`find ${dir} -executable -type f | xargs nm | fgrep ' U ' | sed -e "s/^[ ]*//g" | cut -d' ' -f2 | sort | uniq`
+
+# Now output the symbol table as a structure in a C source file. All
+# undefined symbols are declared as void* types. If the toolchain does
+# any kind of checking for function vs. data objects, then this could
+# faile
+
+echo "#include <nuttx/compiler.h>"
+echo "#include <nuttx/binfmt/symtab.h>"
+echo ""
+
+for var in $varlist; do
+ echo "extern void *${var};"
+done
+
+echo ""
+echo "const struct symtab_s exports[] = "
+echo "{"
+
+for var in $varlist; do
+ echo " {\"${var}\", &${var}},"
+done
+
+echo "};"
+echo ""
+echo "const int nexports = sizeof(exports) / sizeof(struct symtab_s);"
+
diff --git a/apps/examples/posix_spawn/filesystem/redirect/redirect.c b/apps/examples/posix_spawn/filesystem/redirect/redirect.c
new file mode 100644
index 000000000..61638df79
--- /dev/null
+++ b/apps/examples/posix_spawn/filesystem/redirect/redirect.c
@@ -0,0 +1,63 @@
+/****************************************************************************
+ * examples/posix_spawn/filesystem/redirect/redirect.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 <stdio.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, char **argv)
+{
+ int ch;
+
+ printf("Entering the stdin redirection test\n");
+
+ /* stdin should have been redirected to testdata.txt. Read and print until
+ * we hit the end of file.
+ */
+
+ while ((ch = getchar()) != EOF)
+ {
+ putchar(ch);
+ }
+
+ printf("Exit-ing the stdin redirection test\n");
+ return 0;
+}
diff --git a/apps/examples/posix_spawn/filesystem/testdata.txt b/apps/examples/posix_spawn/filesystem/testdata.txt
new file mode 100644
index 000000000..bb581fbb5
--- /dev/null
+++ b/apps/examples/posix_spawn/filesystem/testdata.txt
@@ -0,0 +1,2 @@
+Now is the time for all good men to come to the aid of their party.
+
diff --git a/apps/examples/posix_spawn/spawn_main.c b/apps/examples/posix_spawn/spawn_main.c
new file mode 100644
index 000000000..0ca5f9107
--- /dev/null
+++ b/apps/examples/posix_spawn/spawn_main.c
@@ -0,0 +1,460 @@
+/****************************************************************************
+ * examples/posix_spawn/spawn_main.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 <nuttx/compiler.h>
+
+#include <sys/mount.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <spawn.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <nuttx/ramdisk.h>
+#include <nuttx/binfmt/elf.h>
+#include <nuttx/binfmt/symtab.h>
+
+#include "filesystem/romfs.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* Check configuration. This is not all of the configuration settings that
+ * are required -- only the more obvious.
+ */
+
+#if CONFIG_NFILE_DESCRIPTORS < 1
+# error "You must provide file descriptors via CONFIG_NFILE_DESCRIPTORS in your configuration file"
+#endif
+
+#ifdef CONFIG_BINFMT_DISABLE
+# error "The binary loader is disabled (CONFIG_BINFMT_DISABLE)!"
+#endif
+
+#ifndef CONFIG_ELF
+# error "You must select CONFIG_ELF in your configuration file"
+#endif
+
+#ifndef CONFIG_FS_ROMFS
+# error "You must select CONFIG_FS_ROMFS in your configuration file"
+#endif
+
+#ifdef CONFIG_DISABLE_MOUNTPOINT
+# error "You must not disable mountpoints via CONFIG_DISABLE_MOUNTPOINT in your configuration file"
+#endif
+
+#ifdef CONFIG_BINFMT_DISABLE
+# error "You must not disable loadable modules via CONFIG_BINFMT_DISABLE in your configuration file"
+#endif
+
+/* Describe the ROMFS file system */
+
+#define SECTORSIZE 512
+#define NSECTORS(b) (((b)+SECTORSIZE-1)/SECTORSIZE)
+#define MOUNTPT "/mnt/romfs"
+
+#ifndef CONFIG_EXAMPLES_ELF_DEVMINOR
+# define CONFIG_EXAMPLES_ELF_DEVMINOR 0
+#endif
+
+#ifndef CONFIG_EXAMPLES_ELF_DEVPATH
+# define CONFIG_EXAMPLES_ELF_DEVPATH "/dev/ram0"
+#endif
+
+/* If CONFIG_DEBUG is enabled, use dbg instead of printf so that the
+ * output will be synchronous with the debug output.
+ */
+
+#ifdef CONFIG_CPP_HAVE_VARARGS
+# ifdef CONFIG_DEBUG
+# define message(format, arg...) dbg(format, ##arg)
+# define err(format, arg...) dbg(format, ##arg)
+# else
+# define message(format, arg...) printf(format, ##arg)
+# define err(format, arg...) fprintf(stderr, format, ##arg)
+# endif
+#else
+# ifdef CONFIG_DEBUG
+# define message dbg
+# define err dbg
+# else
+# define message printf
+# define err printf
+# endif
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static unsigned int g_mminitial; /* Initial memory usage */
+static unsigned int g_mmstep; /* Memory Usage at beginning of test step */
+
+static const char delimiter[] =
+ "****************************************************************************";
+static const char g_redirect[] = "redirect";
+static const char g_hello[] = "hello";
+static const char g_data[] = "testdata.txt";
+
+static char fullpath[128];
+
+static char * const g_argv[4] =
+ { "Argument 1", "Argument 2", "Argument 3", NULL };
+
+/****************************************************************************
+ * Symbols from Auto-Generated Code
+ ****************************************************************************/
+
+extern const struct symtab_s exports[];
+extern const int nexports;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mm_update
+ ****************************************************************************/
+
+static void mm_update(FAR unsigned int *previous, FAR const char *msg)
+{
+ struct mallinfo mmcurrent;
+
+ /* Get the current memory usage */
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ /* Show the change from the previous time */
+
+ printf("\nMemory Usage %s:\n", msg);
+ printf(" Before: %8u After: %8u Change: %8d\n",
+ *previous, mmcurrent.uordblks, (int)mmcurrent.uordblks - (int)*previous);
+
+ /* Set up for the next test */
+
+ *previous = mmcurrent.uordblks;
+}
+
+/****************************************************************************
+ * Name: mm_initmonitor
+ ****************************************************************************/
+
+static void mm_initmonitor(void)
+{
+ struct mallinfo mmcurrent;
+
+#ifdef CONFIG_CAN_PASS_STRUCTS
+ mmcurrent = mallinfo();
+#else
+ (void)mallinfo(&mmcurrent);
+#endif
+
+ g_mminitial = mmcurrent.uordblks;
+ g_mmstep = mmcurrent.uordblks;
+
+ printf("Initial memory usage: %d\n", mmcurrent.uordblks);
+}
+
+/****************************************************************************
+ * Name: testheader
+ ****************************************************************************/
+
+static inline void testheader(FAR const char *progname)
+{
+ message("\n%s\n* Executing %s\n%s\n\n", delimiter, progname, delimiter);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: spawn_main
+ ****************************************************************************/
+
+int spawn_main(int argc, char *argv[])
+{
+ posix_spawn_file_actions_t file_actions;
+ posix_spawnattr_t attr;
+ FAR const char *filepath;
+ pid_t pid;
+ int ret;
+
+ /* Initialize the memory monitor */
+
+ mm_initmonitor();
+
+ /* Initialize the ELF binary loader */
+
+ message("Initializing the ELF binary loader\n");
+ ret = elf_initialize();
+ if (ret < 0)
+ {
+ err("ERROR: Initialization of the ELF loader failed: %d\n", ret);
+ exit(1);
+ }
+
+ mm_update(&g_mmstep, "after elf_initialize");
+
+ /* Create a ROM disk for the ROMFS filesystem */
+
+ message("Registering romdisk at /dev/ram%d\n", CONFIG_EXAMPLES_ELF_DEVMINOR);
+ ret = romdisk_register(CONFIG_EXAMPLES_ELF_DEVMINOR, (FAR uint8_t *)romfs_img,
+ NSECTORS(romfs_img_len), SECTORSIZE);
+ if (ret < 0)
+ {
+ err("ERROR: romdisk_register failed: %d\n", ret);
+ elf_uninitialize();
+ exit(1);
+ }
+
+ mm_update(&g_mmstep, "after romdisk_register");
+
+ /* Mount the file system */
+
+ message("Mounting ROMFS filesystem at target=%s with source=%s\n",
+ MOUNTPT, CONFIG_EXAMPLES_ELF_DEVPATH);
+
+ ret = mount(CONFIG_EXAMPLES_ELF_DEVPATH, MOUNTPT, "romfs", MS_RDONLY, NULL);
+ if (ret < 0)
+ {
+ err("ERROR: mount(%s,%s,romfs) failed: %s\n",
+ CONFIG_EXAMPLES_ELF_DEVPATH, MOUNTPT, errno);
+ elf_uninitialize();
+ }
+
+ mm_update(&g_mmstep, "after mount");
+
+ /* Does the system support the PATH variable? Has the PATH variable
+ * already been set? If YES and NO, then set the PATH variable to
+ * the ROMFS mountpoint.
+ */
+
+#if defined(CONFIG_BINFMT_EXEPATH) && !defined(CONFIG_PATH_INITIAL)
+ (void)setenv("PATH", MOUNTPT, 1);
+#endif
+
+ /* Make sure that we are using our symbol take */
+
+ exec_setsymtab(exports, nexports);
+
+ /*************************************************************************
+ * Case 1: Simple program with arguments
+ *************************************************************************/
+
+ /* Output a seperated so that we can clearly discriminate the output of
+ * this program from the others.
+ */
+
+ testheader(g_hello);
+
+ /* Initialize the attributes file actions structure */
+
+ ret = posix_spawn_file_actions_init(&file_actions);
+ if (ret != 0)
+ {
+ err("ERROR: posix_spawn_file_actions_init failed: %d\n", ret);
+ }
+ posix_spawn_file_actions_dump(&file_actions);
+
+ ret = posix_spawnattr_init(&attr);
+ if (ret != 0)
+ {
+ err("ERROR: posix_spawnattr_init failed: %d\n", ret);
+ }
+ posix_spawnattr_dump(&attr);
+
+ mm_update(&g_mmstep, "after file_action/attr init");
+
+ /* If the binary loader does not support the PATH variable, then
+ * create the full path to the executable program. Otherwise,
+ * use the relative path so that the binary loader will have to
+ * search the PATH variable to find the executable.
+ */
+
+#ifdef CONFIG_BINFMT_EXEPATH
+ filepath = g_hello;
+#else
+ snprintf(fullpath, 128, "%s/%s", MOUNTPT, g_hello);
+ filepath = fullpath;
+#endif
+
+ /* Execute the program */
+
+ mm_update(&g_mmstep, "before posix_spawn");
+
+ ret = posix_spawn(&pid, filepath, &file_actions, &attr, NULL, (FAR char * const*)&g_argv);
+ if (ret != 0)
+ {
+ err("ERROR: posix_spawn failed: %d\n", ret);
+ }
+
+ sleep(4);
+ mm_update(&g_mmstep, "after posix_spawn");
+
+ /* Free attibutes and file actions */
+
+ ret = posix_spawn_file_actions_destroy(&file_actions);
+ if (ret != 0)
+ {
+ err("ERROR: posix_spawn_file_actions_destroy failed: %d\n", ret);
+ }
+ posix_spawn_file_actions_dump(&file_actions);
+
+ ret = posix_spawnattr_destroy(&attr);
+ if (ret != 0)
+ {
+ err("ERROR: posix_spawnattr_destroy failed: %d\n", ret);
+ }
+ posix_spawnattr_dump(&attr);
+
+ mm_update(&g_mmstep, "after file_action/attr destruction");
+
+ /*************************************************************************
+ * Case 2: Simple program with redirection of stdin to a file input
+ *************************************************************************/
+
+ /* Output a seperated so that we can clearly discriminate the output of
+ * this program from the others.
+ */
+
+ testheader(g_redirect);
+
+ /* Initialize the attributes file actions structure */
+
+ ret = posix_spawn_file_actions_init(&file_actions);
+ if (ret != 0)
+ {
+ err("ERROR: posix_spawn_file_actions_init failed: %d\n", ret);
+ }
+ posix_spawn_file_actions_dump(&file_actions);
+
+ ret = posix_spawnattr_init(&attr);
+ if (ret != 0)
+ {
+ err("ERROR: posix_spawnattr_init failed: %d\n", ret);
+ }
+ posix_spawnattr_dump(&attr);
+
+ mm_update(&g_mmstep, "after file_action/attr init");
+
+ /* Set up to close stdin (0) and open testdata.txt as the program input */
+
+ ret = posix_spawn_file_actions_addclose(&file_actions, 0);
+ if (ret != 0)
+ {
+ err("ERROR: posix_spawn_file_actions_addclose failed: %d\n", ret);
+ }
+ posix_spawn_file_actions_dump(&file_actions);
+
+ snprintf(fullpath, 128, "%s/%s", MOUNTPT, g_data);
+ ret = posix_spawn_file_actions_addopen(&file_actions, 0, fullpath, O_RDONLY, 0644);
+ if (ret != 0)
+ {
+ err("ERROR: posix_spawn_file_actions_addopen failed: %d\n", ret);
+ }
+ posix_spawn_file_actions_dump(&file_actions);
+
+ mm_update(&g_mmstep, "after adding file_actions");
+
+ /* If the binary loader does not support the PATH variable, then
+ * create the full path to the executable program. Otherwise,
+ * use the relative path so that the binary loader will have to
+ * search the PATH variable to find the executable.
+ */
+
+#ifdef CONFIG_BINFMT_EXEPATH
+ filepath = g_redirect;
+#else
+ snprintf(fullpath, 128, "%s/%s", MOUNTPT, g_redirect);
+ filepath = fullpath;
+#endif
+
+ /* Execute the program */
+
+ mm_update(&g_mmstep, "before posix_spawn");
+
+ ret = posix_spawn(&pid, filepath, &file_actions, &attr, NULL, NULL);
+ if (ret != 0)
+ {
+ err("ERROR: posix_spawn failed: %d\n", ret);
+ }
+
+ sleep(2);
+ mm_update(&g_mmstep, "after posix_spawn");
+
+ /* Free attibutes and file actions */
+
+ ret = posix_spawn_file_actions_destroy(&file_actions);
+ if (ret != 0)
+ {
+ err("ERROR: posix_spawn_file_actions_destroy failed: %d\n", ret);
+ }
+ posix_spawn_file_actions_dump(&file_actions);
+
+ ret = posix_spawnattr_destroy(&attr);
+ if (ret != 0)
+ {
+ err("ERROR: posix_spawnattr_destroy failed: %d\n", ret);
+ }
+ posix_spawnattr_dump(&attr);
+
+ mm_update(&g_mmstep, "after file_action/attr destruction");
+
+ /* Clean-up */
+
+ elf_uninitialize();
+
+ mm_update(&g_mmstep, "End-of-Test");
+ return 0;
+}
diff --git a/apps/examples/pwm/Makefile b/apps/examples/pwm/Makefile
index 3a6f2520a..ece901a99 100644
--- a/apps/examples/pwm/Makefile
+++ b/apps/examples/pwm/Makefile
@@ -83,11 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
-.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
- @touch $@
-context: .context
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
+else
+context:
+endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
diff --git a/apps/examples/qencoder/Makefile b/apps/examples/qencoder/Makefile
index 7d2427c6b..9668796e6 100644
--- a/apps/examples/qencoder/Makefile
+++ b/apps/examples/qencoder/Makefile
@@ -83,13 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
-.context:
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
- @touch $@
-endif
-context: .context
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
+else
+context:
+endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
diff --git a/apps/examples/watchdog/Makefile b/apps/examples/watchdog/Makefile
index 9890959fb..076272fe3 100644
--- a/apps/examples/watchdog/Makefile
+++ b/apps/examples/watchdog/Makefile
@@ -83,11 +83,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
@touch .built
-.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
- @touch $@
-context: .context
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
+else
+context:
+endif
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
diff --git a/apps/include/apps.h b/apps/include/builtin.h
index 520128203..24cf204fa 100644
--- a/apps/include/apps.h
+++ b/apps/include/builtin.h
@@ -1,9 +1,16 @@
/****************************************************************************
- * apps/include/apps.h
+ * apps/include/builtin.h
*
- * Copyright(C) 2011 Uros Platise. All rights reserved.
+ * Originally by:
+ *
+ * Copyright (C) 2011 Uros Platise. All rights reserved.
* Author: Uros Platise <uros.platise@isotel.eu>
*
+ * With subsequent updates, modifications, and general maintenance by:
+ *
+ * Copyright (C) 2012-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:
@@ -33,16 +40,18 @@
*
****************************************************************************/
-#ifndef __APPS_INCLUDE_APPS_H
-#define __APPS_INCLUDE_APPS_H
+#ifndef __APPS_INCLUDE_BUILTIN_H
+#define __APPS_INCLUDE_BUILTIN_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
+
#include <sys/types.h>
-#include <stdint.h>
+
+#include <nuttx/binfmt/builtin.h>
/****************************************************************************
* Pre-processor Definitions
@@ -52,31 +61,10 @@
* Public Types
****************************************************************************/
-struct namedapp_s
-{
- const char *name; /* Invocation name and as seen under /sbin/ */
- int priority; /* Use: SCHED_PRIORITY_DEFAULT */
- int stacksize; /* Desired stack size */
- main_t main; /* Entry point: main(int argc, char *argv[]) */
-};
-
/****************************************************************************
* Public Data
****************************************************************************/
-/* The "bindir" is file system that supports access to the named applications.
- * It is typically mounted under /bin.
- */
-
-#ifdef CONFIG_APPS_BINDIR
-struct mountpt_operations;
-extern const struct mountpt_operations binfs_operations;
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
@@ -86,51 +74,24 @@ extern "C" {
#endif
/****************************************************************************
- * Name: namedapp_isavail
- *
- * Description:
- * Checks for availabiliy of application registerred during compile time.
- *
- * Input Parameter:
- * filename - Name of the linked-in binary to be started.
- *
- * Returned Value:
- * This is an end-user function, so it follows the normal convention:
- * Returns index of builtin application. If it is not found then it
- * returns -1 (ERROR) and sets errno appropriately.
- *
- ****************************************************************************/
-
-EXTERN int namedapp_isavail(FAR const char *appname);
-
-/****************************************************************************
- * Name: namedapp_getname
- *
- * Description:
- * Returns pointer to a name of built-in application pointed by the
- * index.
- *
- * Input Parameter:
- * index, from 0 and on ...
- *
- * Returned Value:
- * Returns valid pointer pointing to the app name if index is valid.
- * Otherwise NULL is returned.
- *
+ * Public Functions
****************************************************************************/
-EXTERN const char *namedapp_getname(int index);
-
/****************************************************************************
- * Name: exec_namedapp
+ * Name: exec_builtin
*
* Description:
- * Executes builtin named application registered during compile time.
+ * Executes builtin applications registered during 'make context' time.
* New application is run in a separate task context (and thread).
*
* Input Parameter:
- * filename - Name of the linked-in binary to be started.
- * argv - Argument list
+ * filename - Name of the linked-in binary to be started.
+ * argv - Argument list
+ * redirfile - If output if redirected, this parameter will be non-NULL
+ * and will provide the full path to the file.
+ * oflags - If output is redirected, this parameter will provide the
+ * open flags to use. This will support file replacement
+ * of appending to an existing file.
*
* Returned Value:
* This is an end-user function, so it follows the normal convention:
@@ -139,11 +100,12 @@ EXTERN const char *namedapp_getname(int index);
*
****************************************************************************/
-EXTERN int exec_namedapp(FAR const char *appname, FAR const char **argv);
+EXTERN int exec_builtin(FAR const char *appname, FAR const char **argv,
+ FAR const char *redirfile, int oflags);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
-#endif /* __APPS_INCLUDE_APPS_H */
+#endif /* __APPS_INCLUDE_BUILTIN_H */
diff --git a/apps/interpreters/Makefile b/apps/interpreters/Makefile
index 867d45f99..f78528714 100644
--- a/apps/interpreters/Makefile
+++ b/apps/interpreters/Makefile
@@ -73,4 +73,4 @@ depend: $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_depend)
clean: $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_clean)
-distclean: clean $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_distclean)
+distclean: $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_distclean)
diff --git a/apps/interpreters/ficl/Makefile b/apps/interpreters/ficl/Makefile
index 990630fb8..3b2dc7ab9 100644
--- a/apps/interpreters/ficl/Makefile
+++ b/apps/interpreters/ficl/Makefile
@@ -108,7 +108,6 @@ context:
depend: .depend
clean:
- $(call DELFILE, .context)
$(call DELFILE, .built)
$(call CLEAN)
diff --git a/apps/namedapp/Kconfig b/apps/namedapp/Kconfig
deleted file mode 100644
index 8d8f03421..000000000
--- a/apps/namedapp/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-
-config NAMEDAPP
- bool "Support named applications"
- default n
- ---help---
- Enable support for named applications. This features assigns a string
- name to an application. This feature is also the underlying requirement
- to support built-in applications in the NuttShell (NSH).
-
-if NAMEDAPP
-endif
diff --git a/apps/namedapp/binfs.c b/apps/namedapp/binfs.c
deleted file mode 100644
index 36e3ace92..000000000
--- a/apps/namedapp/binfs.c
+++ /dev/null
@@ -1,596 +0,0 @@
-/****************************************************************************
- * apps/namedapps/binfs.c
- *
- * Copyright (C) 2011-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/statfs.h>
-#include <sys/stat.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/fs/dirent.h>
-
-#include "namedapp.h"
-
-#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_APPS_BINDIR)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* This structure represents the overall mountpoint state. An instance of this
- * structure is retained as inode private data on each mountpoint that is
- * mounted with a fat32 filesystem.
- */
-
-struct binfs_state_s
-{
- sem_t bm_sem; /* Used to assume thread-safe access */
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static void binfs_semtake(struct binfs_state_s *bm);
-static inline void binfs_semgive(struct binfs_state_s *bm);
-static int binfs_open(FAR struct file *filep, const char *relpath,
- int oflags, mode_t mode);
-static int binfs_close(FAR struct file *filep);
-static ssize_t binfs_read(FAR struct file *filep, char *buffer, size_t buflen);
-static int binfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
-
-static int binfs_opendir(struct inode *mountpt, const char *relpath,
- struct fs_dirent_s *dir);
-static int binfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir);
-static int binfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir);
-
-static int binfs_bind(FAR struct inode *blkdriver, const void *data,
- void **handle);
-static int binfs_unbind(void *handle, FAR struct inode **blkdriver);
-static int binfs_statfs(struct inode *mountpt, struct statfs *buf);
-
-static int binfs_stat(struct inode *mountpt, const char *relpath, struct stat *buf);
-
-/****************************************************************************
- * Private Variables
- ****************************************************************************/
-
-/****************************************************************************
- * Public Variables
- ****************************************************************************/
-
-/* See fs_mount.c -- this structure is explicitly externed there.
- * We use the old-fashioned kind of initializers so that this will compile
- * with any compiler.
- */
-
-const struct mountpt_operations binfs_operations =
-{
- binfs_open, /* open */
- binfs_close, /* close */
- binfs_read, /* read */
- NULL, /* write */
- NULL, /* seek */
- binfs_ioctl, /* ioctl */
- NULL, /* sync */
-
- binfs_opendir, /* opendir */
- NULL, /* closedir */
- binfs_readdir, /* readdir */
- binfs_rewinddir, /* rewinddir */
-
- binfs_bind, /* bind */
- binfs_unbind, /* unbind */
- binfs_statfs, /* statfs */
-
- NULL, /* unlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* rename */
- binfs_stat /* stat */
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: binfs_semtake
- ****************************************************************************/
-
-static void binfs_semtake(struct binfs_state_s *bm)
-{
- /* Take the semaphore (perhaps waiting) */
-
- while (sem_wait(&bm->bm_sem) != 0)
- {
- /* The only case that an error should occur here is if
- * the wait was awakened by a signal.
- */
-
- ASSERT(errno == EINTR);
- }
-}
-
-/****************************************************************************
- * Name: binfs_semgive
- ****************************************************************************/
-
-static inline void binfs_semgive(struct binfs_state_s *bm)
-{
- sem_post(&bm->bm_sem);
-}
-
-/****************************************************************************
- * Name: binfs_open
- ****************************************************************************/
-
-static int binfs_open(FAR struct file *filep, const char *relpath,
- int oflags, mode_t mode)
-{
- struct binfs_state_s *bm;
- int ret = -ENOSYS;
-
- fvdbg("Open '%s'\n", relpath);
-
- /* Sanity checks */
-
- DEBUGASSERT(filep->f_priv == NULL && filep->f_inode != NULL);
-
- /* mountpoint private data from the inode reference from the file
- * structure
- */
-
- bm = (struct binfs_state_s*)filep->f_inode->i_private;
- DEBUGASSERT(bm != NULL);
-
- /* BINFS is read-only. Any attempt to open with any kind of write
- * access is not permitted.
- */
-
- if ((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0)
- {
- fdbg("Only O_RDONLY supported\n");
- ret = -EACCES;
- }
-
- /* Save open-specific state in filep->f_priv */
-
- /* Opening of elements within the pseudo-file system is not yet supported */
-
- return ret;
-}
-
-/****************************************************************************
- * Name: binfs_close
- ****************************************************************************/
-
-static int binfs_close(FAR struct file *filep)
-{
- struct binfs_state_s *bm;
- int ret = -ENOSYS;
-
- fvdbg("Closing\n");
-
- /* Sanity checks */
-
- DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);
-
- /* Recover the open file state from the struct file instance */
- /* bf = filep->f_priv; */
-
- /* Recover the file system state from the inode */
-
- bm = filep->f_inode->i_private;
- DEBUGASSERT(bm != NULL);
-
- /* Free the open file state */
- /* free(bf); */
-
- filep->f_priv = NULL;
-
- /* Since open() is not yet supported, neither is close(). */
-
- return ret;
-}
-
-/****************************************************************************
- * Name: binfs_read
- ****************************************************************************/
-
-static ssize_t binfs_read(FAR struct file *filep, char *buffer, size_t buflen)
-{
- struct binfs_state_s *bm;
-
- fvdbg("Read %d bytes from offset %d\n", buflen, filep->f_pos);
-
- /* Sanity checks */
-
- DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);
-
- /* Recover the open file state data from the struct file instance */
- /* bf = filep->f_priv; */
-
- /* Recover the file system state from the inode */
-
- bm = filep->f_inode->i_private;
- DEBUGASSERT(bm != NULL);
-
- /* Since open is not yet supported, neither is reading */
-
- return -ENOSYS;
-}
-
-/****************************************************************************
- * Name: binfs_ioctl
- ****************************************************************************/
-
-static int binfs_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- struct binfs_state_s *bm;
-
- fvdbg("cmd: %d arg: %08lx\n", cmd, arg);
-
- /* Sanity checks */
-
- DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);
-
- /* Recover the open file state from the struct file instance */
- /* bf = filep->f_priv; */
-
- /* Recover the file system state from the inode */
-
- bm = filep->f_inode->i_private;
- DEBUGASSERT(bm != NULL);
-
- /* No ioctl commands yet supported */
-
- return -ENOTTY;
-}
-
-/****************************************************************************
- * Name: binfs_opendir
- *
- * Description:
- * Open a directory for read access
- *
- ****************************************************************************/
-
-static int binfs_opendir(struct inode *mountpt, const char *relpath,
- struct fs_dirent_s *dir)
-{
- struct binfs_state_s *bm;
- int ret;
-
- fvdbg("relpath: \"%s\"\n", relpath ? relpath : "NULL");
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL);
-
- /* Recover the file system state from the inode instance */
-
- bm = mountpt->i_private;
- binfs_semtake(bm);
-
- /* The requested directory must be the volume-relative "root" directory */
-
- if (relpath && relpath[0] != '\0')
- {
- ret = -ENOENT;
- goto errout_with_semaphore;
- }
-
- /* Set the index to the first entry */
-
- dir->u.binfs.fb_index = 0;
- ret = OK;
-
-errout_with_semaphore:
- binfs_semgive(bm);
- return ret;
-}
-
-/****************************************************************************
- * Name: binfs_readdir
- *
- * Description: Read the next directory entry
- *
- ****************************************************************************/
-
-static int binfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
-{
- struct binfs_state_s *bm;
- unsigned int index;
- int ret;
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL);
-
- /* Recover the file system state from the inode instance */
-
- bm = mountpt->i_private;
- binfs_semtake(bm);
-
- /* Have we reached the end of the directory */
-
- index = dir->u.binfs.fb_index;
- if (namedapps[index].name == NULL)
- {
- /* We signal the end of the directory by returning the
- * special error -ENOENT
- */
-
- fvdbg("Entry %d: End of directory\n", index);
- ret = -ENOENT;
- }
- else
- {
- /* Save the filename and file type */
-
- fvdbg("Entry %d: \"%s\"\n", index, namedapps[index].name);
- dir->fd_dir.d_type = DTYPE_FILE;
- strncpy(dir->fd_dir.d_name, namedapps[index].name, NAME_MAX+1);
-
- /* The application list is terminated by an entry with a NULL name.
- * Therefore, there is at least one more entry in the list.
- */
-
- index++;
-
- /* Set up the next directory entry offset. NOTE that we could use the
- * standard f_pos instead of our own private fb_index.
- */
-
- dir->u.binfs.fb_index = index;
- ret = OK;
- }
-
- binfs_semgive(bm);
- return ret;
-}
-
-/****************************************************************************
- * Name: binfs_rewindir
- *
- * Description: Reset directory read to the first entry
- *
- ****************************************************************************/
-
-static int binfs_rewinddir(struct inode *mountpt, struct fs_dirent_s *dir)
-{
- struct binfs_state_s *bm;
-
- fvdbg("Entry\n");
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL);
-
- /* Recover the file system state from the inode instance */
-
- bm = mountpt->i_private;
- binfs_semtake(bm);
-
- dir->u.binfs.fb_index = 0;
-
- binfs_semgive(bm);
- return OK;
-}
-
-/****************************************************************************
- * Name: binfs_bind
- *
- * Description: This implements a portion of the mount operation. This
- * function allocates and initializes the mountpoint private data and
- * binds the blockdriver inode to the filesystem private data. The final
- * binding of the private data (containing the blockdriver) to the
- * mountpoint is performed by mount().
- *
- ****************************************************************************/
-
-static int binfs_bind(FAR struct inode *blkdriver, const void *data,
- void **handle)
-{
- struct binfs_state_s *bm;
-
- fvdbg("Entry\n");
-
- /* Create an instance of the mountpt state structure */
-
- bm = (struct binfs_state_s *)zalloc(sizeof(struct binfs_state_s));
- if (!bm)
- {
- fdbg("Failed to allocate mountpoint structure\n");
- return -ENOMEM;
- }
-
- /* Initialize the allocated mountpt state structure. The filesystem is
- * responsible for one reference ont the blkdriver inode and does not
- * have to addref() here (but does have to release in ubind().
- */
-
- sem_init(&bm->bm_sem, 0, 1); /* Initialize the semaphore that controls access */
-
- /* Mounted! */
-
- *handle = (void*)bm;
- return OK;
-}
-
-/****************************************************************************
- * Name: binfs_unbind
- *
- * Description: This implements the filesystem portion of the umount
- * operation.
- *
- ****************************************************************************/
-
-static int binfs_unbind(void *handle, FAR struct inode **blkdriver)
-{
- struct binfs_state_s *bm = (struct binfs_state_s*)handle;
-
- fvdbg("Entry\n");
-
-#ifdef CONFIG_DEBUG
- if (!bm)
- {
- return -EINVAL;
- }
-#endif
-
- /* Check if there are sill any files opened on the filesystem. */
-
- /* Release the mountpoint private data */
-
- sem_destroy(&bm->bm_sem);
- return OK;
-}
-
-/****************************************************************************
- * Name: binfs_statfs
- *
- * Description: Return filesystem statistics
- *
- ****************************************************************************/
-
-static int binfs_statfs(struct inode *mountpt, struct statfs *buf)
-{
- struct binfs_state_s *bm;
-
- fvdbg("Entry\n");
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt && mountpt->i_private);
-
- /* Get the mountpoint private data from the inode structure */
-
- bm = mountpt->i_private;
- binfs_semtake(bm);
-
- /* Fill in the statfs info */
-
- memset(buf, 0, sizeof(struct statfs));
- buf->f_type = BINFS_MAGIC;
- buf->f_bsize = 0;
- buf->f_blocks = 0;
- buf->f_bfree = 0;
- buf->f_bavail = 0;
- buf->f_namelen = NAME_MAX;
-
- binfs_semgive(bm);
- return OK;
-}
-
-/****************************************************************************
- * Name: binfs_stat
- *
- * Description: Return information about a file or directory
- *
- ****************************************************************************/
-
-static int binfs_stat(struct inode *mountpt, const char *relpath, struct stat *buf)
-{
- struct binfs_state_s *bm;
- int ret;
-
- fvdbg("Entry\n");
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt && mountpt->i_private);
-
- /* Get the mountpoint private data from the inode structure */
-
- bm = mountpt->i_private;
- binfs_semtake(bm);
-
- /* The requested directory must be the volume-relative "root" directory */
-
- if (relpath && relpath[0] != '\0')
- {
- /* Check if there is a file with this name. */
-
- if (namedapp_isavail(relpath) < 0)
- {
- ret = -ENOENT;
- goto errout_with_semaphore;
- }
-
- /* It's a execute-only file name */
-
- buf->st_mode = S_IFREG|S_IXOTH|S_IXGRP|S_IXUSR;
- }
- else
- {
- /* It's a read/execute-only directory name */
-
- buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR|S_IXOTH|S_IXGRP|S_IXUSR;
- }
-
- /* File/directory size, access block size */
-
- buf->st_size = 0;
- buf->st_blksize = 0;
- buf->st_blocks = 0;
- ret = OK;
-
-errout_with_semaphore:
- binfs_semgive(bm);
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_APPS_BINDIR */
-
diff --git a/apps/namedapp/exec_namedapp.c b/apps/namedapp/exec_namedapp.c
deleted file mode 100644
index 264fca7b9..000000000
--- a/apps/namedapp/exec_namedapp.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/****************************************************************************
- * apps/namedaps/exec_namedapp.c
- *
- * Copyright (C) 2011 Uros Platise. All rights reserved.
- * Author: Uros Platise <uros.platise@isotel.eu>
- *
- * With updates, modifications, and general maintenance by:
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Auther: 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 <apps/apps.h>
-#include <sched.h>
-
-#include <string.h>
-#include <errno.h>
-
-#include "namedapp.h"
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: namedapp_getname
- *
- * Description:
- * Return the name of the application at index in the table of named
- * applications.
- *
- ****************************************************************************/
-
-const char *namedapp_getname(int index)
-{
- if (index < 0 || index >= number_namedapps())
- {
- return NULL;
- }
-
- return namedapps[index].name;
-}
-
-/****************************************************************************
- * Name: namedapp_isavail
- *
- * Description:
- * Return the index into the table of applications for the applicaiton with
- * the name 'appname'.
- *
- ****************************************************************************/
-
-int namedapp_isavail(FAR const char *appname)
-{
- int i;
-
- for (i = 0; namedapps[i].name; i++)
- {
- if (!strcmp(namedapps[i].name, appname))
- {
- return i;
- }
- }
-
- set_errno(ENOENT);
- return ERROR;
-}
-
-/****************************************************************************
- * Name: namedapp_isavail
- *
- * Description:
- * Execute the application with name 'appname', providing the arguments
- * in the argv[] array.
- *
- * Returned Value:
- * On success, the task ID of the named application is returned. On
- * failure, -1 (ERROR) is returned an the errno value is set appropriately.
- *
- ****************************************************************************/
-
-int exec_namedapp(FAR const char *appname, FAR const char **argv)
-{
- pid_t pid;
- int index;
-
- /* Verify that an application with this name exists */
-
- index = namedapp_isavail(appname);
- if (index >= 0)
- {
- /* Disable pre-emption. This means that although we start the named
- * application here, it will not actually run until pre-emption is
- * re-enabled below.
- */
-
- sched_lock();
-
- /* Start the named application task */
-
- pid = TASK_CREATE(namedapps[index].name, namedapps[index].priority,
- namedapps[index].stacksize, namedapps[index].main,
- (argv) ? &argv[1] : (const char **)NULL);
-
- /* 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
- if (pid > 0)
- {
- struct sched_param param;
-
- /* Pre-emption is disabled so the task creation and the
- * following operation will be atomic. The priority of the
- * new task cannot yet have changed from its initial value.
- */
-
- param.sched_priority = namedapps[index].priority;
- sched_setscheduler(pid, SCHED_RR, &param);
- }
-#endif
- /* Now let the named application run */
-
- sched_unlock();
-
- /* Return the task ID of the new task if the task was sucessfully
- * started. Otherwise, pid will be ERROR (and the errno value will
- * be set appropriately).
- */
-
- return pid;
- }
-
- /* Return ERROR with errno set appropriately */
-
- return ERROR;
-}
diff --git a/apps/namedapp/namedapp_list.h b/apps/namedapp/namedapp_list.h
new file mode 100644
index 000000000..72d1fa52d
--- /dev/null
+++ b/apps/namedapp/namedapp_list.h
@@ -0,0 +1,42 @@
+/* List of application requirements, generated during make context. */
+{ "math_demo", SCHED_PRIORITY_DEFAULT, 8192, math_demo_main },
+{ "control_demo", SCHED_PRIORITY_DEFAULT, 2048, control_demo_main },
+{ "kalman_demo", SCHED_PRIORITY_MAX - 30, 2048, kalman_demo_main },
+{ "reboot", SCHED_PRIORITY_DEFAULT, 2048, reboot_main },
+{ "perf", SCHED_PRIORITY_DEFAULT, 2048, perf_main },
+{ "top", SCHED_PRIORITY_DEFAULT - 10, 3000, top_main },
+{ "boardinfo", SCHED_PRIORITY_DEFAULT, 2048, boardinfo_main },
+{ "mixer", SCHED_PRIORITY_DEFAULT, 4096, mixer_main },
+{ "eeprom", SCHED_PRIORITY_DEFAULT, 4096, eeprom_main },
+{ "param", SCHED_PRIORITY_DEFAULT, 4096, param_main },
+{ "bl_update", SCHED_PRIORITY_DEFAULT, 4096, bl_update_main },
+{ "preflight_check", SCHED_PRIORITY_DEFAULT, 2048, preflight_check_main },
+{ "delay_test", SCHED_PRIORITY_DEFAULT, 2048, delay_test_main },
+{ "uorb", SCHED_PRIORITY_DEFAULT, 4096, uorb_main },
+{ "mavlink", SCHED_PRIORITY_DEFAULT, 2048, mavlink_main },
+{ "mavlink_onboard", SCHED_PRIORITY_DEFAULT, 2048, mavlink_onboard_main },
+{ "gps", SCHED_PRIORITY_DEFAULT, 2048, gps_main },
+{ "commander", SCHED_PRIORITY_MAX - 30, 2048, commander_main },
+{ "sdlog", SCHED_PRIORITY_MAX - 30, 2048, sdlog_main },
+{ "sensors", SCHED_PRIORITY_MAX-5, 4096, sensors_main },
+{ "ardrone_interface", SCHED_PRIORITY_MAX - 15, 2048, ardrone_interface_main },
+{ "multirotor_att_control", SCHED_PRIORITY_MAX - 15, 2048, multirotor_att_control_main },
+{ "multirotor_pos_control", SCHED_PRIORITY_MAX - 25, 2048, multirotor_pos_control_main },
+{ "fixedwing_att_control", SCHED_PRIORITY_MAX - 30, 2048, fixedwing_att_control_main },
+{ "fixedwing_pos_control", SCHED_PRIORITY_MAX - 30, 2048, fixedwing_pos_control_main },
+{ "position_estimator", SCHED_PRIORITY_DEFAULT, 4096, position_estimator_main },
+{ "attitude_estimator_ekf", SCHED_PRIORITY_DEFAULT, 2048, attitude_estimator_ekf_main },
+{ "ms5611", SCHED_PRIORITY_DEFAULT, 2048, ms5611_main },
+{ "hmc5883", SCHED_PRIORITY_DEFAULT, 4096, hmc5883_main },
+{ "mpu6000", SCHED_PRIORITY_DEFAULT, 4096, mpu6000_main },
+{ "bma180", SCHED_PRIORITY_DEFAULT, 2048, bma180_main },
+{ "l3gd20", SCHED_PRIORITY_DEFAULT, 2048, l3gd20_main },
+{ "px4io", SCHED_PRIORITY_DEFAULT, 2048, px4io_main },
+{ "blinkm", SCHED_PRIORITY_DEFAULT, 2048, blinkm_main },
+{ "tone_alarm", SCHED_PRIORITY_DEFAULT, 2048, tone_alarm_main },
+{ "adc", SCHED_PRIORITY_DEFAULT, 2048, adc_main },
+{ "fmu", SCHED_PRIORITY_DEFAULT, 2048, fmu_main },
+{ "hil", SCHED_PRIORITY_DEFAULT, 2048, hil_main },
+{ "tests", SCHED_PRIORITY_DEFAULT, 12000, tests_main },
+{ "sercon", SCHED_PRIORITY_DEFAULT, 2048, sercon_main },
+{ "serdis", SCHED_PRIORITY_DEFAULT, 2048, serdis_main },
diff --git a/apps/namedapp/namedapp_proto.h b/apps/namedapp/namedapp_proto.h
new file mode 100644
index 000000000..09f5b4156
--- /dev/null
+++ b/apps/namedapp/namedapp_proto.h
@@ -0,0 +1,42 @@
+/* List of application entry points, generated during make context. */
+EXTERN int math_demo_main(int argc, char *argv[]);
+EXTERN int control_demo_main(int argc, char *argv[]);
+EXTERN int kalman_demo_main(int argc, char *argv[]);
+EXTERN int reboot_main(int argc, char *argv[]);
+EXTERN int perf_main(int argc, char *argv[]);
+EXTERN int top_main(int argc, char *argv[]);
+EXTERN int boardinfo_main(int argc, char *argv[]);
+EXTERN int mixer_main(int argc, char *argv[]);
+EXTERN int eeprom_main(int argc, char *argv[]);
+EXTERN int param_main(int argc, char *argv[]);
+EXTERN int bl_update_main(int argc, char *argv[]);
+EXTERN int preflight_check_main(int argc, char *argv[]);
+EXTERN int delay_test_main(int argc, char *argv[]);
+EXTERN int uorb_main(int argc, char *argv[]);
+EXTERN int mavlink_main(int argc, char *argv[]);
+EXTERN int mavlink_onboard_main(int argc, char *argv[]);
+EXTERN int gps_main(int argc, char *argv[]);
+EXTERN int commander_main(int argc, char *argv[]);
+EXTERN int sdlog_main(int argc, char *argv[]);
+EXTERN int sensors_main(int argc, char *argv[]);
+EXTERN int ardrone_interface_main(int argc, char *argv[]);
+EXTERN int multirotor_att_control_main(int argc, char *argv[]);
+EXTERN int multirotor_pos_control_main(int argc, char *argv[]);
+EXTERN int fixedwing_att_control_main(int argc, char *argv[]);
+EXTERN int fixedwing_pos_control_main(int argc, char *argv[]);
+EXTERN int position_estimator_main(int argc, char *argv[]);
+EXTERN int attitude_estimator_ekf_main(int argc, char *argv[]);
+EXTERN int ms5611_main(int argc, char *argv[]);
+EXTERN int hmc5883_main(int argc, char *argv[]);
+EXTERN int mpu6000_main(int argc, char *argv[]);
+EXTERN int bma180_main(int argc, char *argv[]);
+EXTERN int l3gd20_main(int argc, char *argv[]);
+EXTERN int px4io_main(int argc, char *argv[]);
+EXTERN int blinkm_main(int argc, char *argv[]);
+EXTERN int tone_alarm_main(int argc, char *argv[]);
+EXTERN int adc_main(int argc, char *argv[]);
+EXTERN int fmu_main(int argc, char *argv[]);
+EXTERN int hil_main(int argc, char *argv[]);
+EXTERN int tests_main(int argc, char *argv[]);
+EXTERN int sercon_main(int argc, char *argv[]);
+EXTERN int serdis_main(int argc, char *argv[]);
diff --git a/apps/nshlib/Kconfig b/apps/nshlib/Kconfig
index 17b107b8f..e60e9c480 100644
--- a/apps/nshlib/Kconfig
+++ b/apps/nshlib/Kconfig
@@ -15,12 +15,12 @@ if NSH_LIBRARY
config NSH_BUILTIN_APPS
bool "Enable built-in applications"
default y
- depends on NAMEDAPP
+ depends on BUILTIN
---help---
- Support external registered, "named" applications that can be
+ Support external registered, "built-in" applications that can be
executed from the NSH command line (see apps/README.txt for
- more information). This options requires support for named applications
- (NAMEDAPP).
+ more information). This options requires support for builtin
+ applications (BUILTIN).
menu "Disable Individual commands"
diff --git a/apps/nshlib/Makefile b/apps/nshlib/Makefile
index 73325e899..5c5269685 100644
--- a/apps/nshlib/Makefile
+++ b/apps/nshlib/Makefile
@@ -44,7 +44,7 @@ CSRCS = nsh_init.c nsh_parse.c nsh_console.c nsh_fscmds.c nsh_ddcmd.c \
nsh_proccmds.c nsh_mmcmds.c nsh_envcmds.c nsh_dbgcmds.c
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
-CSRCS += nsh_apps.c
+CSRCS += nsh_builtin.c
endif
ifeq ($(CONFIG_NSH_ROMFSETC),y)
@@ -130,7 +130,6 @@ clean:
$(call CLEAN)
distclean: clean
- $(call DELFILE, .context)
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)
diff --git a/apps/nshlib/README.txt b/apps/nshlib/README.txt
index bc626e699..006839628 100644
--- a/apps/nshlib/README.txt
+++ b/apps/nshlib/README.txt
@@ -945,7 +945,7 @@ NSH-Specific Configuration Settings
the configs/<board-name>/defconfig file:
* CONFIG_NSH_BUILTIN_APPS
- Support external registered, "named" applications that can be
+ Support external registered, "builtin" applications that can be
executed from the NSH command line (see apps/README.txt for
more information).
diff --git a/apps/nshlib/nsh.h b/apps/nshlib/nsh.h
index a046a384f..253a803f8 100644
--- a/apps/nshlib/nsh.h
+++ b/apps/nshlib/nsh.h
@@ -491,7 +491,8 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline);
/* Application interface */
#ifdef CONFIG_NSH_BUILTIN_APPS
-int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, FAR char **argv);
+int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
+ FAR char **argv, FAR const char *redirfile, int oflags);
#endif
/* Working directory support */
diff --git a/apps/nshlib/nsh_apps.c b/apps/nshlib/nsh_builtin.c
index 7dbaf9ba8..ba39e8dfe 100644
--- a/apps/nshlib/nsh_apps.c
+++ b/apps/nshlib/nsh_builtin.c
@@ -1,10 +1,16 @@
/****************************************************************************
- * apps/nshlib/nsh_apps.c
+ * apps/nshlib/nsh_builtin.c
+ *
+ * Originally by:
*
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2011 Uros Platise. All rights reserved.
* Author: Uros Platise <uros.platise@isotel.eu>
*
+ * With subsequent updates, modifications, and general maintenance by:
+ *
+ * Copyright (C) 2011-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:
@@ -48,7 +54,8 @@
#include <errno.h>
#include <string.h>
-#include <apps/apps.h>
+#include <nuttx/binfmt/builtin.h>
+#include <apps/builtin.h>
#include "nsh.h"
#include "nsh_console.h"
@@ -84,13 +91,13 @@
****************************************************************************/
/****************************************************************************
- * Name: nsh_execapp
+ * Name: nsh_builtin
*
* Description:
* Attempt to execute the application task whose name is 'cmd'
*
* Returned Value:
- * <0 If exec_namedapp() fails, then the negated errno 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).
@@ -104,8 +111,8 @@
*
****************************************************************************/
-int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
- FAR char **argv)
+int nsh_builtin(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
+ FAR char **argv, FAR const char *redirfile, int oflags)
{
int ret = OK;
@@ -119,7 +126,7 @@ int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
* applications.
*/
- ret = exec_namedapp(cmd, (FAR const char **)argv);
+ ret = exec_builtin(cmd, (FAR const char **)argv, redirfile, oflags);
if (ret >= 0)
{
/* The application was successfully started (but still blocked because
@@ -191,7 +198,7 @@ int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
#if !defined(CONFIG_SCHED_WAITPID) || !defined(CONFIG_NSH_DISABLEBG)
{
struct sched_param param;
- sched_getparam(0, &param);
+ sched_getparam(ret, &param);
nsh_output(vtbl, "%s [%d:%d]\n", cmd, ret, param.sched_priority);
/* Backgrounded commands always 'succeed' as long as we can start
@@ -205,13 +212,13 @@ int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
sched_unlock();
- /* If exec_namedapp() or waitpid() failed, then return the negated errno
- * value.
+ /* If exec_builtin() or waitpid() failed, then return -1 (ERROR) with the
+ * errno value set appropriately.
*/
if (ret < 0)
{
- return -errno;
+ return ERROR;
}
return ret;
diff --git a/apps/nshlib/nsh_codeccmd.c b/apps/nshlib/nsh_codeccmd.c
new file mode 100644
index 000000000..779fc5ecd
--- /dev/null
+++ b/apps/nshlib/nsh_codeccmd.c
@@ -0,0 +1,538 @@
+/****************************************************************************
+ * apps/nshlib/nsh_codeccmd.c
+ *
+ * This file is part of NuttX, contributed by Darcy Gong
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Darcy Gong 2012-10-30
+ *
+ * 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_NETUTILS_CODECS
+
+#include <sys/stat.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sched.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <errno.h>
+#include <debug.h>
+
+#if defined(CONFIG_NSH_DISABLE_URLENCODE) && defined(CONFIG_NSH_DISABLE_URLDECODE)
+# undef CONFIG_CODECS_URLCODE
+#endif
+
+#ifdef CONFIG_CODECS_URLCODE
+#include <apps/netutils/urldecode.h>
+#endif
+
+#if defined(CONFIG_NSH_DISABLE_BASE64ENC) && defined(CONFIG_NSH_DISABLE_BASE64ENC)
+# undef CONFIG_CODECS_BASE64
+#endif
+
+#ifdef CONFIG_CODECS_BASE64
+#include <apps/netutils/base64.h>
+#endif
+
+#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
+#include <apps/netutils/md5.h>
+#endif
+
+#include "nsh.h"
+#include "nsh_console.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_NSH_CODECS_BUFSIZE
+# define CONFIG_NSH_CODECS_BUFSIZE 128
+#endif
+
+#define CODEC_MODE_URLENCODE 1
+#define CODEC_MODE_URLDECODE 2
+#define CODEC_MODE_BASE64ENC 3
+#define CODEC_MODE_BASE64DEC 4
+#define CODEC_MODE_HASH_MD5 5
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef void (*codec_callback_t)(FAR char *src_buff, int src_buff_len,
+ FAR char *dst_buff, FAR int *dst_buff_len,
+ int mode);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: urlencode_cb
+ ****************************************************************************/
+
+#if defined(CONFIG_CODECS_URLCODE) && !defined(CONFIG_NSH_DISABLE_URLENCODE)
+static void urlencode_cb(FAR char *src_buff, int src_buff_len,
+ FAR char *dst_buff, FAR int *dst_buff_len, int mode)
+{
+ urlencode(src_buff,src_buff_len,dst_buff,dst_buff_len);
+}
+#endif
+
+/****************************************************************************
+ * Name: urldecode_cb
+ ****************************************************************************/
+
+#if defined(CONFIG_CODECS_URLCODE) && !defined(CONFIG_NSH_DISABLE_URLDECODE)
+static void urldecode_cb(FAR char *src_buff, int src_buff_len, FAR char *dst_buff,
+ FAR int *dst_buff_len, int mode)
+{
+ urldecode(src_buff,src_buff_len,dst_buff,dst_buff_len);
+}
+#endif
+
+/****************************************************************************
+ * Name: b64enc_cb
+ ****************************************************************************/
+
+#if defined(CONFIG_CODECS_BASE64) && !defined(CONFIG_NSH_DISABLE_BASE64ENC)
+static void b64enc_cb(FAR char *src_buff, int src_buff_len, FAR char *dst_buff,
+ FAR int *dst_buff_len, int mode)
+{
+ if (mode == 0)
+ {
+ //dst_buff =
+ base64_encode((unsigned char *)src_buff, src_buff_len,
+ (unsigned char *)dst_buff, (size_t *)dst_buff_len);
+ }
+ else
+ {
+ //dst_buff =
+ base64w_encode((unsigned char *)src_buff, src_buff_len,
+ (unsigned char *)dst_buff, (size_t *)dst_buff_len);
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: b64dec_cb
+ ****************************************************************************/
+
+#if defined(CONFIG_CODECS_BASE64) && !defined(CONFIG_NSH_DISABLE_BASE64DEC)
+static void b64dec_cb(FAR char *src_buff, int src_buff_len, FAR char *dst_buff,
+ FAR int *dst_buff_len, int mode)
+{
+ if (mode == 0)
+ {
+ //dst_buff =
+ base64_decode((unsigned char *)src_buff, src_buff_len,
+ (unsigned char *)dst_buff, (size_t *)dst_buff_len);
+ }
+ else
+ {
+ //dst_buff =
+ base64w_decode((unsigned char *)src_buff, src_buff_len,
+ (unsigned char *)dst_buff,(size_t *)dst_buff_len);
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: md5_cb
+ ****************************************************************************/
+
+#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
+static void md5_cb(FAR char *src_buff, int src_buff_len, FAR char *dst_buff,
+ FAR int *dst_buff_len, int mode)
+{
+ MD5Update((MD5_CTX *)dst_buff, (unsigned char *)src_buff, src_buff_len);
+}
+#endif
+
+/****************************************************************************
+ * Name: calc_codec_buffsize
+ ****************************************************************************/
+
+static int calc_codec_buffsize(int src_buffsize, uint8_t mode)
+{
+ switch (mode)
+ {
+ case CODEC_MODE_URLENCODE:
+ return src_buffsize*3+1;
+ case CODEC_MODE_URLDECODE:
+ return src_buffsize+1;
+ case CODEC_MODE_BASE64ENC:
+ return ((src_buffsize + 2)/ 3 * 4)+1;
+ case CODEC_MODE_BASE64DEC:
+ return (src_buffsize / 4 * 3 + 2)+1;
+ case CODEC_MODE_HASH_MD5:
+ return 32+1;
+ default:
+ return src_buffsize+1;
+ }
+}
+
+/****************************************************************************
+ * Name: cmd_codecs_proc
+ ****************************************************************************/
+
+static int cmd_codecs_proc(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv,
+ uint8_t mode, codec_callback_t func)
+{
+#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
+ static const unsigned char hex_chars[] = "0123456789abcdef";
+ MD5_CTX ctx;
+ unsigned char mac[16];
+ char *pSrc;
+ char *pDest;
+#endif
+
+ char *localfile = NULL;
+ char *src_buffer = NULL;
+ char *buffer = NULL;
+ char *fullpath = NULL;
+ const char *fmt;
+ char *s_data;
+ bool badarg = false;
+ bool is_file = false;
+ bool is_websafe=false;
+ int option;
+ int fd = -1;
+ int buff_len = 0;
+ int src_buff_len = 0;
+ int i = 0;
+ int ret = OK;
+
+ /* Get the command options */
+
+ while ((option = getopt(argc, argv, ":fw")) != ERROR)
+ {
+ switch (option)
+ {
+ case 'f':
+ is_file = true;
+ break;
+
+#ifdef CONFIG_CODECS_BASE64
+ case 'w':
+ is_websafe = true;
+
+ if (!(mode == CODEC_MODE_BASE64ENC || mode == CODEC_MODE_BASE64DEC))
+ {
+ badarg = true;
+ }
+ break;
+#endif
+ case ':':
+ nsh_output(vtbl, g_fmtargrequired, argv[0]);
+ badarg = true;
+ break;
+
+ case '?':
+ default:
+ nsh_output(vtbl, g_fmtarginvalid, argv[0]);
+ badarg = true;
+ break;
+ }
+ }
+
+ /* If a bad argument was encountered, then return without processing the command */
+
+ if (badarg)
+ {
+ return ERROR;
+ }
+
+ /* There should be exactly on parameter left on the command-line */
+
+ if (optind == argc-1)
+ {
+ s_data = argv[optind];
+ }
+ else if (optind >= argc)
+ {
+ fmt = g_fmttoomanyargs;
+ goto errout;
+ }
+ else
+ {
+ fmt = g_fmtargrequired;
+ goto errout;
+ }
+
+#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
+ if (mode == CODEC_MODE_HASH_MD5)
+ {
+ MD5Init(&ctx);
+ }
+#endif
+
+ if (is_file)
+ {
+ /* Get the local file name */
+
+ localfile = s_data;
+
+ /* Get the full path to the local file */
+
+ fullpath = nsh_getfullpath(vtbl, localfile);
+
+ /* Open the local file for writing */
+
+ fd = open(fullpath, O_RDONLY|O_TRUNC, 0644);
+ if (fd < 0)
+ {
+ nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
+ ret = ERROR;
+ goto exit;
+ }
+
+ src_buffer = malloc(CONFIG_NSH_CODECS_BUFSIZE+2);
+#if defined(CONFIG_CODECS_BASE64) && !defined(CONFIG_NSH_DISABLE_BASE64ENC)
+ if (mode == CODEC_MODE_BASE64ENC)
+ {
+ src_buff_len = CONFIG_NSH_CODECS_BUFSIZE / 3 * 3;
+ }
+ else
+#endif
+ {
+ src_buff_len = CONFIG_NSH_CODECS_BUFSIZE;
+ }
+
+ buff_len = calc_codec_buffsize(src_buff_len+2, mode);
+ buffer = malloc(buff_len);
+ while(true)
+ {
+ memset(src_buffer, 0, src_buff_len+2);
+ ret=read(fd, src_buffer, src_buff_len);
+ if (ret < 0)
+ {
+ nsh_output(vtbl, g_fmtcmdfailed, argv[0], "read", NSH_ERRNO);
+ ret = ERROR;
+ goto exit;
+ }
+ else if(ret==0)
+ {
+ break;
+ }
+
+#if defined(CONFIG_CODECS_URLCODE) && !defined(CONFIG_NSH_DISABLE_URLDECODE)
+ if (mode == CODEC_MODE_URLDECODE)
+ {
+ if (src_buffer[src_buff_len-1]=='%')
+ {
+ ret += read(fd,&src_buffer[src_buff_len],2);
+ }
+ else if (src_buffer[src_buff_len-2]=='%')
+ {
+ ret += read(fd,&src_buffer[src_buff_len],1);
+ }
+ }
+#endif
+ memset(buffer, 0, buff_len);
+ if (func)
+ {
+#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
+ if (mode == CODEC_MODE_HASH_MD5)
+ {
+ func(src_buffer, ret, (char *)&ctx, &buff_len,0);
+ }
+ else
+#endif
+ {
+ func(src_buffer, ret, buffer, &buff_len,(is_websafe)?1:0);
+ nsh_output(vtbl, "%s", buffer);
+ }
+ }
+
+ buff_len = calc_codec_buffsize(src_buff_len+2, mode);
+ }
+
+#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
+ if (mode == CODEC_MODE_HASH_MD5)
+ {
+ MD5Final(mac, &ctx);
+ pSrc = (char *)&mac;
+ pDest = buffer;
+ for(i=0;i<16;i++,pSrc++)
+ {
+ *pDest++ = hex_chars[(*pSrc) >> 4];
+ *pDest++ = hex_chars[(*pSrc) & 0x0f];
+ }
+
+ *pDest='\0';
+ nsh_output(vtbl, "%s\n", buffer);
+ }
+#endif
+ ret = OK;
+ goto exit;
+ }
+ else
+ {
+ src_buffer = s_data;
+ src_buff_len = strlen(s_data);
+ buff_len = calc_codec_buffsize(src_buff_len, mode);
+ buffer = malloc(buff_len);
+ buffer[0]=0;
+ if (!buffer)
+ {
+ fmt = g_fmtcmdoutofmemory;
+ goto errout;
+ }
+
+ memset(buffer, 0, buff_len);
+ if (func)
+ {
+#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
+ if (mode == CODEC_MODE_HASH_MD5)
+ {
+ func(src_buffer, src_buff_len, (char *)&ctx, &buff_len, 0);
+ MD5Final(mac, &ctx);
+ pSrc = (char *)&mac;
+ pDest = buffer;
+ for(i=0;i<16;i++,pSrc++)
+ {
+ *pDest++ = hex_chars[(*pSrc) >> 4];
+ *pDest++ = hex_chars[(*pSrc) & 0x0f];
+ }
+
+ *pDest='\0';
+ }
+ else
+#endif
+ {
+ func(src_buffer, src_buff_len, buffer, &buff_len,(is_websafe)?1:0);
+ }
+ }
+
+ nsh_output(vtbl, "%s\n",buffer);
+ src_buffer = NULL;
+ goto exit;
+ }
+
+exit:
+ if (fd >= 0)
+ {
+ close(fd);
+ }
+
+ if (fullpath)
+ {
+ free(fullpath);
+ }
+
+ if (src_buffer)
+ {
+ free(src_buffer);
+ }
+
+ if (buffer)
+ {
+ free(buffer);
+ }
+
+ return ret;
+
+errout:
+ nsh_output(vtbl, fmt, argv[0]);
+ ret = ERROR;
+ goto exit;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cmd_urlencode
+ ****************************************************************************/
+
+#if defined(CONFIG_CODECS_URLCODE) && !defined(CONFIG_NSH_DISABLE_URLENCODE)
+int cmd_urlencode(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+{
+ return cmd_codecs_proc(vtbl, argc, argv, CODEC_MODE_URLENCODE, urlencode_cb);
+}
+#endif
+
+/****************************************************************************
+ * Name: cmd_urldecode
+ ****************************************************************************/
+
+#if defined(CONFIG_CODECS_URLCODE) && !defined(CONFIG_NSH_DISABLE_URLDECODE)
+int cmd_urldecode(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+{
+ return cmd_codecs_proc(vtbl, argc, argv, CODEC_MODE_URLDECODE, urldecode_cb);
+}
+#endif
+
+/****************************************************************************
+ * Name: cmd_base64encode
+ ****************************************************************************/
+
+#if defined(CONFIG_CODECS_BASE64) && !defined(CONFIG_NSH_DISABLE_BASE64ENC)
+int cmd_base64encode(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+{
+ return cmd_codecs_proc(vtbl, argc, argv, CODEC_MODE_BASE64ENC, b64enc_cb);
+}
+#endif
+
+/****************************************************************************
+ * Name: cmd_base64decode
+ ****************************************************************************/
+
+#if defined(CONFIG_CODECS_BASE64) && !defined(CONFIG_NSH_DISABLE_BASE64DEC)
+int cmd_base64decode(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+{
+ return cmd_codecs_proc(vtbl, argc, argv, CODEC_MODE_BASE64DEC, b64dec_cb);
+}
+#endif
+
+/****************************************************************************
+ * Name: cmd_md5
+ ****************************************************************************/
+
+#if defined(CONFIG_CODECS_HASH_MD5) && !defined(CONFIG_NSH_DISABLE_MD5)
+int cmd_md5(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+{
+ return cmd_codecs_proc(vtbl,argc,argv,CODEC_MODE_HASH_MD5,md5_cb);
+}
+#endif
+
+#endif /* CONFIG_NETUTILS_CODECS */
diff --git a/apps/nshlib/nsh_mntcmds.c b/apps/nshlib/nsh_mntcmds.c
index 690d027ca..f8e3a142a 100644
--- a/apps/nshlib/nsh_mntcmds.c
+++ b/apps/nshlib/nsh_mntcmds.c
@@ -45,10 +45,13 @@
#include <stdint.h>
#include <stdbool.h>
+#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <debug.h>
+#include <nuttx/fs/nfs.h>
+
#include "nsh.h"
#include "nsh_console.h"
@@ -128,9 +131,9 @@ static int mount_handler(FAR const char *mountpoint,
break;
#endif
-#ifdef CONFIG_APPS_BINDIR
+#ifdef CONFIG_FS_BINFS
case BINFS_MAGIC:
- fstype = "bindir";
+ fstype = "binfs";
break;
#endif
@@ -195,9 +198,11 @@ int cmd_df(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
defined(CONFIG_FS_READABLE) && !defined(CONFIG_NSH_DISABLE_MOUNT)
int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
- FAR char *source;
- FAR char *target;
- FAR char *filesystem = NULL;
+ FAR const char *source;
+ FAR char *fullsource;
+ FAR const char *target;
+ FAR char *fulltarget;
+ FAR const char *filesystem = NULL;
bool badarg = false;
int option;
int ret;
@@ -245,19 +250,32 @@ int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
return ERROR;
}
- /* There are two required arguments after the options: the source and target
- * paths.
+ /* There may be one or two required arguments after the options: the source
+ * and target paths. Some file systems do not require the source parameter
+ * so if there is only one parameter left, it must be the target.
*/
- if (optind + 2 < argc)
+ if (optind >= argc)
{
- nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
+ nsh_output(vtbl, g_fmtargrequired, argv[0]);
return ERROR;
}
- else if (optind + 2 > argc)
+
+ source = NULL;
+ target = argv[optind];
+ optind++;
+
+ if (optind < argc)
{
- nsh_output(vtbl, g_fmtargrequired, argv[0]);
- return ERROR;
+ source = target;
+ target = argv[optind];
+ optind++;
+
+ if (optind < argc)
+ {
+ nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
+ return ERROR;
+ }
}
/* While the above parsing for the -t argument looks nice, the -t argument
@@ -274,29 +292,44 @@ int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
* working directory.
*/
- source = nsh_getfullpath(vtbl, argv[optind]);
- if (!source)
+ fullsource = NULL;
+ fulltarget = NULL;
+
+ if (source)
{
- return ERROR;
+ fullsource = nsh_getfullpath(vtbl, source);
+ if (!fullsource)
+ {
+ return ERROR;
+ }
}
- target = nsh_getfullpath(vtbl, argv[optind+1]);
- if (!target)
+ fulltarget = nsh_getfullpath(vtbl, target);
+ if (!fulltarget)
{
- nsh_freefullpath(source);
- return ERROR;
+ ret = ERROR;
+ goto errout;
}
/* Perform the mount */
- ret = mount(source, target, filesystem, 0, NULL);
+ ret = mount(fullsource, fulltarget, filesystem, 0, NULL);
if (ret < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "mount", NSH_ERRNO);
}
- nsh_freefullpath(source);
- nsh_freefullpath(target);
+errout:
+ if (fullsource)
+ {
+ nsh_freefullpath(fullsource);
+ }
+
+ if (fulltarget)
+ {
+ nsh_freefullpath(fulltarget);
+ }
+
return ret;
}
#endif
diff --git a/apps/nshlib/nsh_netcmds.c b/apps/nshlib/nsh_netcmds.c
index 371d30460..506950e14 100644
--- a/apps/nshlib/nsh_netcmds.c
+++ b/apps/nshlib/nsh_netcmds.c
@@ -67,6 +67,7 @@
#if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) && \
!defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_DISABLE_SIGNALS)
# include <apps/netutils/uiplib.h>
+# include <apps/netutils/resolv.h>
#endif
#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0
diff --git a/apps/nshlib/nsh_parse.c b/apps/nshlib/nsh_parse.c
index 27068acff..ef4125a63 100644
--- a/apps/nshlib/nsh_parse.c
+++ b/apps/nshlib/nsh_parse.c
@@ -1,7 +1,7 @@
/****************************************************************************
* apps/nshlib/nsh_parse.c
*
- * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -59,7 +59,7 @@
#endif
#ifdef CONFIG_NSH_BUILTIN_APPS
-# include <apps/apps.h>
+# include <nuttx/binfmt/builtin.h>
#endif
#include <apps/nsh.h>
@@ -72,7 +72,7 @@
/* Argument list size
*
- * argv[0]: The command name.
+ * argv[0]: The command name.
* argv[1]: The beginning of argument (up to CONFIG_NSH_MAXARGUMENTS)
* argv[argc-3]: Possibly '>' or '>>'
* argv[argc-2]: Possibly <file>
@@ -226,7 +226,7 @@ static const struct cmdmap_s g_cmdmap[] =
{ "help", cmd_help, 1, 3, "[-v] [<cmd>]" },
# endif
#endif
-
+
#if CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_NSH_DISABLE_HEXDUMP
{ "hexdump", cmd_hexdump, 2, 2, "<file or device>" },
@@ -301,7 +301,7 @@ static const struct cmdmap_s g_cmdmap[] =
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_FS_READABLE)
# ifndef CONFIG_NSH_DISABLE_MOUNT
- { "mount", cmd_mount, 1, 5, "[-t <fstype> <block-device> <mount-point>]" },
+ { "mount", cmd_mount, 1, 5, "[-t <fstype> [<block-device>] <mount-point>]" },
# endif
#endif
@@ -605,7 +605,7 @@ static inline void help_builtins(FAR struct nsh_vtbl_s *vtbl)
/* List the set of available built-in commands */
nsh_output(vtbl, "\nBuiltin Apps:\n");
- for (i = 0; (name = namedapp_getname(i)) != NULL; i++)
+ for (i = 0; (name = builtin_getname(i)) != NULL; i++)
{
nsh_output(vtbl, " %s\n", name);
}
@@ -723,15 +723,11 @@ static int cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
* Name: nsh_execute
*
* Description:
- * Exectue the command in argv[0]
+ * Execute the command in argv[0]
*
* Returned Value:
- * <0 If exec_namedapp() fails, then the negated errno value
- * is returned.
* -1 (ERRROR) if the command was unsuccessful
* 0 (OK) if the command was successful
- * 1 if an application task was spawned successfully, but
- * returned failure exit status.
*
****************************************************************************/
@@ -751,21 +747,6 @@ static int nsh_execute(FAR struct nsh_vtbl_s *vtbl, int argc, char *argv[])
*/
cmd = argv[0];
-
- /* Try to find a command in the application library. */
-
-#ifdef CONFIG_NSH_BUILTIN_APPS
- ret = nsh_execapp(vtbl, cmd, argv);
-
- /* If the built-in application was successfully started, return OK
- * or 1 (if the application returned a non-zero exit status).
- */
-
- if (ret >= 0)
- {
- return ret;
- }
-#endif
/* See if the command is one that we understand */
@@ -1352,7 +1333,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
/* Parse all of the arguments following the command name. The form
* of argv is:
*
- * argv[0]: The command name.
+ * argv[0]: The command name.
* argv[1]: The beginning of argument (up to CONFIG_NSH_MAXARGUMENTS)
* argv[argc-3]: Possibly '>' or '>>'
* argv[argc-2]: Possibly <file>
@@ -1410,6 +1391,47 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
}
}
+ /* Check if the maximum number of arguments was exceeded */
+
+ if (argc > CONFIG_NSH_MAXARGUMENTS)
+ {
+ nsh_output(vtbl, g_fmttoomanyargs, cmd);
+ }
+
+ /* Does this command correspond to a builtin command?
+ * nsh_builtin() 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_BUILTIN_APPS
+ ret = nsh_builtin(vtbl, argv[0], argv, redirfile, oflags);
+ if (ret >= 0)
+ {
+ /* nsh_builtin() 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
+
/* Redirected output? */
if (vtbl->np.np_redirect)
@@ -1431,23 +1453,13 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
}
}
- /* Check if the maximum number of arguments was exceeded */
-
- if (argc > CONFIG_NSH_MAXARGUMENTS)
- {
- nsh_output(vtbl, g_fmttoomanyargs, cmd);
- }
-
/* Handle the case where the command is executed in background.
- * However is app is to be started as namedapp new process will
- * be created anyway, so skip this step. */
+ * However is app is to be started as builtin new process will
+ * be created anyway, so skip this step.
+ */
#ifndef CONFIG_NSH_DISABLEBG
- if (vtbl->np.np_bg
-#ifdef CONFIG_NSH_BUILTIN_APPS
- && namedapp_isavail(argv[0]) < 0
-#endif
- )
+ if (vtbl->np.np_bg)
{
struct sched_param param;
struct nsh_vtbl_s *bkgvtbl;
@@ -1514,6 +1526,7 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
priority = min_priority;
}
}
+
param.sched_priority = priority;
}
@@ -1553,8 +1566,6 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
*
* -1 (ERRROR) if the command was unsuccessful
* 0 (OK) if the command was successful
- * 1 if an application task was spawned successfully, but
- * returned failure exit status.
*/
ret = nsh_execute(vtbl, argc, argv);
@@ -1568,11 +1579,11 @@ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline)
nsh_undirect(vtbl, save);
}
- /* Treat both errors and non-zero return codes as "errors" so that
- * it is possible to test for non-zero returns in nsh scripts.
+ /* Mark errors so that it is possible to test for non-zero return values
+ * in nsh scripts.
*/
- if (ret != OK)
+ if (ret < 0)
{
goto errout;
}
diff --git a/apps/system/Makefile b/apps/system/Makefile
index 9955a6b2c..057fbcf77 100644
--- a/apps/system/Makefile
+++ b/apps/system/Makefile
@@ -73,4 +73,4 @@ depend: $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_depend)
clean: $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_clean)
-distclean: clean $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_distclean)
+distclean: $(foreach SDIR, $(INSTALLED_DIRS), $(SDIR)_distclean)
diff --git a/apps/system/free/Makefile b/apps/system/free/Makefile
index dada00d99..58ca7956c 100644
--- a/apps/system/free/Makefile
+++ b/apps/system/free/Makefile
@@ -92,11 +92,14 @@ $(COBJS): %$(OBJEXT): %.c
# Register application
-.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
- $(Q) touch $@
-context: .context
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
+else
+context:
+endif
# Create dependencies
@@ -111,7 +114,6 @@ clean:
$(call CLEAN)
distclean: clean
- $(call DELFILE, .context)
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)
diff --git a/apps/system/i2c/Makefile b/apps/system/i2c/Makefile
index 029d2b6fe..1ed7a2fae 100644
--- a/apps/system/i2c/Makefile
+++ b/apps/system/i2c/Makefile
@@ -68,7 +68,7 @@ STACKSIZE = 2048
# Build targets
all: .built
-.PHONY: .context context .depend depend clean distclean
+.PHONY: context .depend depend clean distclean
$(AOBJS): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
@@ -80,11 +80,14 @@ $(COBJS): %$(OBJEXT): %.c
$(call ARCHIVE, $(BIN), $(OBJS))
$(Q) touch .built
-.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
- $(Q) touch $@
-context: .context
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
+else
+context:
+endif
.depend: Makefile $(SRCS)
$(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
@@ -97,7 +100,6 @@ clean:
$(call CLEAN)
distclean: clean
- $(call DELFILE, .context)
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)
diff --git a/apps/system/install/Makefile b/apps/system/install/Makefile
index 6a02d859f..07d42887a 100644
--- a/apps/system/install/Makefile
+++ b/apps/system/install/Makefile
@@ -93,11 +93,14 @@ $(COBJS): %$(OBJEXT): %.c
# Register application
-.context:
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
- $(Q) touch $@
-context: .context
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
+else
+context:
+endif
# Create dependencies
@@ -112,7 +115,6 @@ clean:
$(call CLEAN)
distclean: clean
- $(call DELFILE, .context)
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)
diff --git a/apps/system/readline/Makefile b/apps/system/readline/Makefile
index 3a48d324e..040fd2e28 100644
--- a/apps/system/readline/Makefile
+++ b/apps/system/readline/Makefile
@@ -100,7 +100,6 @@ clean:
$(call CLEAN)
distclean: clean
- $(call DELFILE, .context)
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)
diff --git a/apps/systemcmds/perf/perf.c b/apps/systemcmds/perf/perf.c
index ced942fd6..64443d019 100644
--- a/apps/systemcmds/perf/perf.c
+++ b/apps/systemcmds/perf/perf.c
@@ -39,6 +39,7 @@
#include <nuttx/config.h>
#include <unistd.h>
#include <stdio.h>
+#include <string.h>
#include "systemlib/perf_counter.h"
@@ -63,6 +64,15 @@ __EXPORT int perf_main(int argc, char *argv[]);
int perf_main(int argc, char *argv[])
{
+ if (argc > 1) {
+ if (strcmp(argv[1], "reset") == 0) {
+ perf_reset_all();
+ return 0;
+ }
+ printf("Usage: perf <reset>\n");
+ return -1;
+ }
+
perf_print_all();
fflush(stdout);
return 0;
diff --git a/apps/systemlib/perf_counter.c b/apps/systemlib/perf_counter.c
index ff15ef479..879f4715a 100644
--- a/apps/systemlib/perf_counter.c
+++ b/apps/systemlib/perf_counter.c
@@ -219,6 +219,40 @@ perf_end(perf_counter_t handle)
}
void
+perf_reset(perf_counter_t handle)
+{
+ if (handle == NULL)
+ return;
+
+ switch (handle->type) {
+ case PC_COUNT:
+ ((struct perf_ctr_count *)handle)->event_count = 0;
+ break;
+
+ case PC_ELAPSED: {
+ struct perf_ctr_elapsed *pce = (struct perf_ctr_elapsed *)handle;
+ pce->event_count = 0;
+ pce->time_start = 0;
+ pce->time_total = 0;
+ pce->time_least = 0;
+ pce->time_most = 0;
+ break;
+ }
+
+ case PC_INTERVAL: {
+ struct perf_ctr_interval *pci = (struct perf_ctr_interval *)handle;
+ pci->event_count = 0;
+ pci->time_event = 0;
+ pci->time_first = 0;
+ pci->time_last = 0;
+ pci->time_least = 0;
+ pci->time_most = 0;
+ break;
+ }
+ }
+}
+
+void
perf_print_counter(perf_counter_t handle)
{
if (handle == NULL)
@@ -270,3 +304,14 @@ perf_print_all(void)
handle = (perf_counter_t)sq_next(&handle->link);
}
}
+
+void
+perf_reset_all(void)
+{
+ perf_counter_t handle = (perf_counter_t)sq_peek(&perf_counters);
+
+ while (handle != NULL) {
+ perf_reset(handle);
+ handle = (perf_counter_t)sq_next(&handle->link);
+ }
+}
diff --git a/apps/systemlib/perf_counter.h b/apps/systemlib/perf_counter.h
index 6e6c80d5b..5c2cb15b2 100644
--- a/apps/systemlib/perf_counter.h
+++ b/apps/systemlib/perf_counter.h
@@ -97,6 +97,14 @@ __EXPORT extern void perf_begin(perf_counter_t handle);
*/
__EXPORT extern void perf_end(perf_counter_t handle);
+/**
+ * Reset a performance event.
+ *
+ * This call resets performance counter to initial state
+ *
+ * @param handle The handle returned from perf_alloc.
+ */
+__EXPORT extern void perf_reset(perf_counter_t handle);
/**
* Print one performance counter.
@@ -110,6 +118,11 @@ __EXPORT extern void perf_print_counter(perf_counter_t handle);
*/
__EXPORT extern void perf_print_all(void);
+/**
+ * Reset all of the performance counters.
+ */
+__EXPORT extern void perf_reset_all(void);
+
__END_DECLS
#endif