Merge NuttX r5527

This commit is contained in:
px4dev
2013-01-17 01:00:46 -08:00
228 changed files with 15512 additions and 1913 deletions
+1 -1
View File
@@ -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"
+4 -4
View File
@@ -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
+7 -9
View File
@@ -40,9 +40,9 @@
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 += 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 +57,11 @@ 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
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_HELLO_BUILTIN),y)
CNTXTDIRS += hello
endif
ifeq ($(CONFIG_EXAMPLES_HELLOXX_BUILTIN),y)
CNTXTDIRS += helloxx
endif
@@ -120,7 +118,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
+94 -8
View File
@@ -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
^^^^^^^^^^^^
+5 -4
View File
@@ -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
+5 -4
View File
@@ -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
+5 -4
View File
@@ -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
+9 -4
View File
@@ -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)
$(call REGISTER,$(APPNAME2),$(PRIORITY2),$(STACKSIZE2),$(APPNAME2)_main)
@touch $@
context: .context
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME2)_main.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,$(APPNAME2),$(PRIORITY2),$(STACKSIZE2),$(APPNAME2)_main)
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
+6 -5
View File
@@ -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
+5 -4
View File
@@ -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
+13 -4
View File
@@ -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
+29 -17
View File
@@ -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()
+14
View File
@@ -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;
}
+63
View File
@@ -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();
}
+103
View File
@@ -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;
}
+269
View File
@@ -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 */
+29
View File
@@ -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
+130
View File
@@ -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
@@ -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)
@@ -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;
}
+51
View File
@@ -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);"
@@ -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;
}
@@ -0,0 +1,2 @@
Now is the time for all good men to come to the aid of their party.
+460
View File
@@ -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;
}
+6 -3
View File
@@ -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
+5 -4
View File
@@ -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
+6 -3
View File
@@ -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