diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-01-10 21:39:57 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-01-10 21:39:57 +0000 |
commit | f011bd7ef6f91261969ae08655016b8a7b41a796 (patch) | |
tree | 131c191493d4b1db094cddb4ce39e9d75c539daf /apps | |
parent | 6f241ed0443cc265d7a079f4bbf8d2d67be939ff (diff) | |
download | px4-firmware-f011bd7ef6f91261969ae08655016b8a7b41a796.tar.gz px4-firmware-f011bd7ef6f91261969ae08655016b8a7b41a796.tar.bz2 px4-firmware-f011bd7ef6f91261969ae08655016b8a7b41a796.zip |
Added a test of posix_spawn()
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5507 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'apps')
-rw-r--r-- | apps/ChangeLog.txt | 1 | ||||
-rw-r--r-- | apps/examples/Kconfig | 1 | ||||
-rw-r--r-- | apps/examples/elf/tests/Makefile | 18 | ||||
-rwxr-xr-x | apps/examples/elf/tests/mksymtab.sh | 18 | ||||
-rw-r--r-- | apps/examples/nxflat/tests/Makefile | 4 | ||||
-rw-r--r-- | apps/examples/posix_spawn/Kconfig | 29 | ||||
-rw-r--r-- | apps/examples/posix_spawn/Makefile | 110 | ||||
-rw-r--r-- | apps/examples/posix_spawn/filesystem/Makefile | 85 | ||||
-rwxr-xr-x | apps/examples/posix_spawn/filesystem/mksymtab.sh | 51 | ||||
-rw-r--r-- | apps/examples/posix_spawn/filesystem/program/Makefile | 59 | ||||
-rw-r--r-- | apps/examples/posix_spawn/filesystem/program/program.c | 60 | ||||
-rw-r--r-- | apps/examples/posix_spawn/filesystem/testdata.txt | 2 | ||||
-rw-r--r-- | apps/examples/posix_spawn/spawn_main.c | 356 |
13 files changed, 766 insertions, 28 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt index cd15b430d..6b63527a7 100644 --- a/apps/ChangeLog.txt +++ b/apps/ChangeLog.txt @@ -461,4 +461,5 @@ the USB HID keyboard report data. * apps/examples/wlan: Remove non-functional example. * apps/examples/ostest/vfork.c: Added a test of vfork(). + * apps/exampes/posix_spawn: Added a test of poxis_spawn(). diff --git a/apps/examples/Kconfig b/apps/examples/Kconfig index b0cbd7088..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" diff --git a/apps/examples/elf/tests/Makefile b/apps/examples/elf/tests/Makefile index 778dd6480..755199506 100644 --- a/apps/examples/elf/tests/Makefile +++ b/apps/examples/elf/tests/Makefile @@ -66,7 +66,7 @@ SYMTAB_SRC = $(TESTS_DIR)/symtab.c define DIR_template $(1)_$(2): - @$(MAKE) -C $(1) $(3) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)" CROSSDEV=$(CROSSDEV) + $(Q) $(MAKE) -C $(1) $(3) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)" CROSSDEV=$(CROSSDEV) endef all: $(ROMFS_HDR) $(DIRLIST_HDR) $(SYMTAB_SRC) @@ -87,7 +87,7 @@ install: $(foreach DIR, $(BUILD_SUBDIRS), $(DIR)_install) # Create the romfs directory $(ROMFS_DIR): - @mkdir $(ROMFS_DIR) + $(Q) mkdir $(ROMFS_DIR) # Populate the romfs directory @@ -96,25 +96,25 @@ populate: $(ROMFS_DIR) build install # Create the romfs.img file from the populated romfs directory $(ROMFS_IMG): populate - @genromfs -f $@ -d $(ROMFS_DIR) -V "ELFTEST" + $(Q) genromfs -f $@ -d $(ROMFS_DIR) -V "ELFTEST" # Create the romfs.h header file from the romfs.img file $(ROMFS_HDR) : $(ROMFS_IMG) - @(cd $(TESTS_DIR); xxd -i romfs.img | sed -e "s/^unsigned/static const unsigned/g" >$@) + $(Q) (cd $(TESTS_DIR); xxd -i romfs.img | sed -e "s/^unsigned/static const unsigned/g" >$@) # Create the dirlist.h header file from the romfs directory $(DIRLIST_HDR) : populate - @$(TESTS_DIR)/mkdirlist.sh $(ROMFS_DIR) >$@ + $(Q) $(TESTS_DIR)/mkdirlist.sh $(ROMFS_DIR) >$@ -# Create the exported symbol table list from the derived *-thunk.S files +# Create the exported symbol table $(SYMTAB_SRC): build - @$(TESTS_DIR)/mksymtab.sh -t varlist.tmp $(ROMFS_DIR) >$@ + $(Q) $(TESTS_DIR)/mksymtab.sh $(ROMFS_DIR) >$@ # Clean each subdirectory clean: $(foreach DIR, $(ALL_SUBDIRS), $(DIR)_clean) - @rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB_SRC) varlist.tmp - @rm -rf $(ROMFS_DIR) $(DIRLIST_HDR) + $(Q) rm -f $(ROMFS_HDR) $(DIRLIST_HDR) $(ROMFS_IMG) $(SYMTAB_SRC) + $(Q) rm -rf $(ROMFS_DIR) diff --git a/apps/examples/elf/tests/mksymtab.sh b/apps/examples/elf/tests/mksymtab.sh index 56be10f73..51408a89c 100755 --- a/apps/examples/elf/tests/mksymtab.sh +++ b/apps/examples/elf/tests/mksymtab.sh @@ -1,22 +1,6 @@ #!/bin/bash -usage="Usage: $0 [-t <tmp-file>] <test-dir-path>" - -# Check for the optional tempory file name - -tmpfile=varlist.tmp -if [ "X${1}" = "X-t" ]; then - shift - tmpfile=$1 - shift - - if [ -z "$tmpfile" ]; then - echo "ERROR: Missing <tmpfile>" - echo "" - echo $usage - exit 1 - fi -fi +usage="Usage: $0 <test-dir-path>" # Check for the required ROMFS directory path diff --git a/apps/examples/nxflat/tests/Makefile b/apps/examples/nxflat/tests/Makefile index 4979c7fd4..53e43288f 100644 --- a/apps/examples/nxflat/tests/Makefile +++ b/apps/examples/nxflat/tests/Makefile @@ -97,7 +97,7 @@ $(SYMTAB): build # Clean each subdirectory clean: $(foreach DIR, $(SUBDIRS), $(DIR)_clean) - @rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB) - @rm -rf $(ROMFS_DIR) $(ROMFS_DIRLIST) + @rm -f $(ROMFS_HDR) $(ROMFS_DIRLIST) $(ROMFS_IMG) $(SYMTAB) + @rm -rf $(ROMFS_DIR) 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..d21c8f856 --- /dev/null +++ b/apps/examples/posix_spawn/Makefile @@ -0,0 +1,110 @@ +############################################################################ +# 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: .built +.PHONY: really_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 real +# build. This is done because we need a fresh build context after auto- +# generating the source files. + +really_build: $(OBJS) + $(call ARCHIVE, $(BIN), $(OBJS)) + @touch .built + +.built: + @$(MAKE) -C filesystem TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV) + @$(MAKE) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" really_build + +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 DELFILE, .built) + $(call CLEAN) + +distclean: clean + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/apps/examples/posix_spawn/filesystem/Makefile b/apps/examples/posix_spawn/filesystem/Makefile new file mode 100644 index 000000000..19a02bb80 --- /dev/null +++ b/apps/examples/posix_spawn/filesystem/Makefile @@ -0,0 +1,85 @@ +############################################################################ +# 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 program clean install populate + +# Create the romfs directory + +$(ROMFS_DIR): + $(Q) mkdir $(ROMFS_DIR) + +# Build the test program + +program: $(ROMFS_DIR) + $(Q) $(MAKE) -C program program TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)" + +# Install the test program in the romfs directory + +install: program testdata.txt + $(Q) $(MAKE) -C program install TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)" + $(Q) install --mode=0644 testdata.txt $(ROMFS_DIR)/testdata.txt + +# Create the romfs.img file from the romfs directory + +$(ROMFS_IMG): install + $(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): program + $(Q) $(FILESYSTEM_DIR)$(DELIM)mksymtab.sh $(ROMFS_DIR) >$@ + +# Clean each subdirectory + +clean: + $(Q) $(MAKE) -C program 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/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/program/Makefile b/apps/examples/posix_spawn/filesystem/program/Makefile new file mode 100644 index 000000000..cf55797b2 --- /dev/null +++ b/apps/examples/posix_spawn/filesystem/program/Makefile @@ -0,0 +1,59 @@ +############################################################################ +# examples/posix_spawn/filesystem/program/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 + +BIN = program + +SRCS = $(BIN).c +OBJS = $(SRCS:.c=.o) + +all: $(BIN) + +$(OBJS): %.o: %.c + @echo "CC: $<" + $(Q) $(CC) -c $(CELFFLAGS) $< -o $@ + +$(BIN): $(OBJS) + @echo "LD: $<" + $(Q) $(LD) $(LDELFFLAGS) -o $@ $^ + +clean: + $(call DELFILE, $(BIN)) + $(call CLEAN) + +install: + $(Q) mkdir -p $(ROMFS_DIR) + $(Q) install --mode=0755 $(BIN) $(ROMFS_DIR)/$(BIN) diff --git a/apps/examples/posix_spawn/filesystem/program/program.c b/apps/examples/posix_spawn/filesystem/program/program.c new file mode 100644 index 000000000..f63b559c8 --- /dev/null +++ b/apps/examples/posix_spawn/filesystem/program/program.c @@ -0,0 +1,60 @@ +/**************************************************************************** + * examples/posix_spawn/filesystem/program/program.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; + + /* stdin should have been redirected to testdata.txt. Read and print until + * we hit the end of file. + */ + + while ((ch = getchar()) != EOF) + { + putchar(ch); + } + + 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..3e3a7b1b1 --- /dev/null +++ b/apps/examples/posix_spawn/spawn_main.c @@ -0,0 +1,356 @@ +/**************************************************************************** + * 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 program[] = "program"; +static const char data[] = "testdata.txt"; + +static char fullpath[128]; + +/**************************************************************************** + * 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); + + /* Output a seperated so that we can clearly discriminate the output of + * this program from the others. + */ + + testheader(program); + + /* 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); + } + + ret = posix_spawnattr_init(&attr); + if (ret != 0) + { + err("ERROR: posix_spawnattr_init failed: %d\n", ret); + } + + /* 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); + } + + snprintf(fullpath, 128, "%s/%s", MOUNTPT, 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); + } + + /* 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 = program; +#else + snprintf(fullpath, 128, "%s/%s", MOUNTPT, program); + 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(1); + mm_update(&g_mmstep, "after posix_spawn"); + + /* Clean-up */ + + (void)posix_spawn_file_actions_destroy(&file_actions); + (void)posix_spawnattr_destroy(&attr); + elf_uninitialize(); + + mm_update(&g_mmstep, "End-of-Test"); + return 0; +} |