aboutsummaryrefslogtreecommitdiff
path: root/apps/examples
diff options
context:
space:
mode:
authorpx4dev <px4@purgatory.org>2013-01-23 18:46:12 -0800
committerpx4dev <px4@purgatory.org>2013-01-23 18:46:12 -0800
commit1ce1d4460b1c7884490118ea356bf61ffbd31163 (patch)
tree92c2fdbf63bd517b5a954f267ebdefdb23445df0 /apps/examples
parent72a0a4a71cd48c268d581436461a1f97db85f1d3 (diff)
parent8685f63c72259d18304fd9a04099e5cfa17829ba (diff)
downloadpx4-firmware-1ce1d4460b1c7884490118ea356bf61ffbd31163.tar.gz
px4-firmware-1ce1d4460b1c7884490118ea356bf61ffbd31163.tar.bz2
px4-firmware-1ce1d4460b1c7884490118ea356bf61ffbd31163.zip
Merge pull request #183 from PX4/nuttx-merge-5527
Nuttx merge 5527
Diffstat (limited to 'apps/examples')
-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.c103
-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
27 files changed, 1559 insertions, 81 deletions
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/examples/ostest/vfork.c b/apps/examples/ostest/vfork.c
new file mode 100644
index 000000000..4e1b8c892
--- /dev/null
+++ b/apps/examples/ostest/vfork.c
@@ -0,0 +1,103 @@
+/****************************************************************************
+ * examples/ostest/vfork.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 <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "ostest.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#if defined(CONFIG_ARCH_HAVE_VFORK) && !defined(CONFIG_DISABLE_SIGNALS)
+static volatile bool g_vforkchild;
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int vfork_test(void)
+{
+#if defined(CONFIG_ARCH_HAVE_VFORK) && !defined(CONFIG_DISABLE_SIGNALS)
+ pid_t pid;
+
+ 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.
+ */
+
+ 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