From 697666a4f68ea2cd163cbba71dd703ee7b8efab5 Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 10 Jan 2013 21:39:57 +0000 Subject: Added a test of posix_spawn() git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5507 42af7a65-404d-4744-a932-0658087f49c3 --- apps/examples/posix_spawn/Kconfig | 29 ++ apps/examples/posix_spawn/Makefile | 110 +++++++ apps/examples/posix_spawn/filesystem/Makefile | 85 +++++ apps/examples/posix_spawn/filesystem/mksymtab.sh | 51 +++ .../posix_spawn/filesystem/program/Makefile | 59 ++++ .../posix_spawn/filesystem/program/program.c | 60 ++++ apps/examples/posix_spawn/filesystem/testdata.txt | 2 + apps/examples/posix_spawn/spawn_main.c | 356 +++++++++++++++++++++ 8 files changed, 752 insertions(+) create mode 100644 apps/examples/posix_spawn/Kconfig create mode 100644 apps/examples/posix_spawn/Makefile create mode 100644 apps/examples/posix_spawn/filesystem/Makefile create mode 100755 apps/examples/posix_spawn/filesystem/mksymtab.sh create mode 100644 apps/examples/posix_spawn/filesystem/program/Makefile create mode 100644 apps/examples/posix_spawn/filesystem/program/program.c create mode 100644 apps/examples/posix_spawn/filesystem/testdata.txt create mode 100644 apps/examples/posix_spawn/spawn_main.c (limited to 'apps/examples/posix_spawn') 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 +# +# 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 +# +# 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 " + +# Check for the required ROMFS directory path + +dir=$1 +if [ -z "$dir" ]; then + echo "ERROR: Missing " + 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 " +echo "#include " +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 +# +# 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 + * + * 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 + +/**************************************************************************** + * 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 + * + * 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 +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#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; +} -- cgit v1.2.3