summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-01-11 16:53:44 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-01-11 16:53:44 +0000
commit7272d1e7473fc1ce1d0a29c7287260402ca2420e (patch)
tree46e6b528a6ace37a9ec35f2e4c1d7d3fe8b510f5
parent8b26f2afdf93273f95e24840b68df485f971f89a (diff)
downloadnuttx-7272d1e7473fc1ce1d0a29c7287260402ca2420e.tar.gz
nuttx-7272d1e7473fc1ce1d0a29c7287260402ca2420e.tar.bz2
nuttx-7272d1e7473fc1ce1d0a29c7287260402ca2420e.zip
Various changes while debugging posix_spawn
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5510 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--apps/examples/elf/tests/hello/hello.c12
-rw-r--r--apps/examples/posix_spawn/Makefile17
-rw-r--r--apps/examples/posix_spawn/filesystem/Makefile25
-rw-r--r--apps/examples/posix_spawn/filesystem/hello/Makefile59
-rw-r--r--apps/examples/posix_spawn/filesystem/hello/hello.c78
-rw-r--r--apps/examples/posix_spawn/filesystem/redirect/Makefile (renamed from apps/examples/posix_spawn/filesystem/program/Makefile)4
-rw-r--r--apps/examples/posix_spawn/filesystem/redirect/redirect.c (renamed from apps/examples/posix_spawn/filesystem/program/program.c)5
-rw-r--r--apps/examples/posix_spawn/spawn_main.c118
-rw-r--r--nuttx/ChangeLog2
-rw-r--r--nuttx/include/spawn.h12
-rw-r--r--nuttx/libc/spawn/Make.defs8
-rw-r--r--nuttx/libc/spawn/lib_ps.c13
-rw-r--r--nuttx/libc/spawn/lib_psa_dump.c127
-rw-r--r--nuttx/libc/spawn/lib_psa_init.c3
-rw-r--r--nuttx/libc/spawn/lib_psfa_dump.c129
-rw-r--r--nuttx/sched/task_vfork.c61
16 files changed, 629 insertions, 44 deletions
diff --git a/apps/examples/elf/tests/hello/hello.c b/apps/examples/elf/tests/hello/hello.c
index 6b1d079d8..bc4953e12 100644
--- a/apps/examples/elf/tests/hello/hello.c
+++ b/apps/examples/elf/tests/hello/hello.c
@@ -63,13 +63,13 @@ int main(int argc, char **argv)
{
printf("argv[%d]\t= ", i);
if (argv[i])
- {
- printf("(0x%p) \"%s\"\n", argv[i], argv[i]);
- }
+ {
+ printf("(0x%p) \"%s\"\n", argv[i], argv[i]);
+ }
else
- {
- printf("NULL?\n");
- }
+ {
+ printf("NULL?\n");
+ }
}
printf("argv[%d]\t= 0x%p\n", argc, argv[argc]);
diff --git a/apps/examples/posix_spawn/Makefile b/apps/examples/posix_spawn/Makefile
index d21c8f856..bda3376d2 100644
--- a/apps/examples/posix_spawn/Makefile
+++ b/apps/examples/posix_spawn/Makefile
@@ -64,8 +64,8 @@ ROOTDEPPATH = --dep-path . --dep-path filesystem
VPATH = filesystem
-all: .built
-.PHONY: really_build clean_filesystem clean depend distclean
+all: build
+.PHONY: build clean_filesystem clean depend distclean
$(AOBJS): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
@@ -74,17 +74,16 @@ $(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
+# 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.
-really_build: $(OBJS)
+build_lib: $(OBJS)
$(call ARCHIVE, $(BIN), $(OBJS))
- @touch .built
-.built:
+build:
@$(MAKE) -C filesystem TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" CROSSDEV=$(CROSSDEV)
- @$(MAKE) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" really_build
+ @$(MAKE) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" build_lib
context:
@@ -100,11 +99,13 @@ 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)
+# There are no dependencies in this directory. We should are code some of
+# more important dependencies here:
+
-include Make.dep
diff --git a/apps/examples/posix_spawn/filesystem/Makefile b/apps/examples/posix_spawn/filesystem/Makefile
index 19a02bb80..2005d060f 100644
--- a/apps/examples/posix_spawn/filesystem/Makefile
+++ b/apps/examples/posix_spawn/filesystem/Makefile
@@ -44,22 +44,28 @@ 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
+.PHONY: all hello redirect clean install populate
# Create the romfs directory
$(ROMFS_DIR):
$(Q) mkdir $(ROMFS_DIR)
-# Build the test program
+# Build the hello test program
-program: $(ROMFS_DIR)
- $(Q) $(MAKE) -C program program TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
+hello: $(ROMFS_DIR)
+ $(Q) $(MAKE) -C hello hello TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
-# Install the test program in the romfs directory
+# Build the redirection test program
-install: program testdata.txt
- $(Q) $(MAKE) -C program install TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
+redirect: $(ROMFS_DIR)
+ $(Q) $(MAKE) -C redirect redirect TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
+
+# Install the test programs in the romfs directory
+
+install: hello redirect testdata.txt
+ $(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
# Create the romfs.img file from the romfs directory
@@ -74,12 +80,13 @@ $(ROMFS_HDR) : $(ROMFS_IMG)
# Create the exported symbol table
-$(SYMTAB_SRC): program
+$(SYMTAB_SRC): hello/hello redirect/redirect testdata.txt
$(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) $(MAKE) -C hello clean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
+ $(Q) $(MAKE) -C redirect clean TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)" ROMFS_DIR="$(ROMFS_DIR)"
$(Q) rm -f $(ROMFS_HDR) $(ROMFS_IMG) $(SYMTAB_SRC)
$(Q) rm -rf $(ROMFS_DIR)
diff --git a/apps/examples/posix_spawn/filesystem/hello/Makefile b/apps/examples/posix_spawn/filesystem/hello/Makefile
new file mode 100644
index 000000000..5cd80411b
--- /dev/null
+++ b/apps/examples/posix_spawn/filesystem/hello/Makefile
@@ -0,0 +1,59 @@
+############################################################################
+# examples/elf/tests/hello/Makefile
+#
+# Copyright (C) 2012 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+-include $(TOPDIR)/Make.defs
+
+BIN = hello
+
+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 $(BIN) $(ROMFS_DIR)/$(BIN)
diff --git a/apps/examples/posix_spawn/filesystem/hello/hello.c b/apps/examples/posix_spawn/filesystem/hello/hello.c
new file mode 100644
index 000000000..1b269d85f
--- /dev/null
+++ b/apps/examples/posix_spawn/filesystem/hello/hello.c
@@ -0,0 +1,78 @@
+/****************************************************************************
+ * examples/posix_spawn/filesystem/hello/hello.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, char **argv)
+{
+ int i;
+
+ /* Mandatory "Hello, world!" */
+
+ puts("Getting ready to say \"Hello, world\"\n");
+ printf("Hello, world!\n");
+ puts("It has been said.\n");
+
+ /* Print arguments */
+
+ printf("argc\t= %d\n", argc);
+ printf("argv\t= 0x%p\n", argv);
+
+ for (i = 0; i < argc; i++)
+ {
+ printf("argv[%d]\t= ", i);
+ if (argv[i])
+ {
+ printf("(0x%p) \"%s\"\n", argv[i], argv[i]);
+ }
+ else
+ {
+ printf("NULL?\n");
+ }
+ }
+
+ printf("argv[%d]\t= 0x%p\n", argc, argv[argc]);
+ printf("Goodbye, world!\n");
+ return 0;
+}
diff --git a/apps/examples/posix_spawn/filesystem/program/Makefile b/apps/examples/posix_spawn/filesystem/redirect/Makefile
index cf55797b2..421ff014a 100644
--- a/apps/examples/posix_spawn/filesystem/program/Makefile
+++ b/apps/examples/posix_spawn/filesystem/redirect/Makefile
@@ -1,5 +1,5 @@
############################################################################
-# examples/posix_spawn/filesystem/program/Makefile
+# examples/posix_spawn/filesystem/redirect/Makefile
#
# Copyright (C) 2013 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
@@ -35,7 +35,7 @@
-include $(TOPDIR)/Make.defs
-BIN = program
+BIN = redirect
SRCS = $(BIN).c
OBJS = $(SRCS:.c=.o)
diff --git a/apps/examples/posix_spawn/filesystem/program/program.c b/apps/examples/posix_spawn/filesystem/redirect/redirect.c
index f63b559c8..61638df79 100644
--- a/apps/examples/posix_spawn/filesystem/program/program.c
+++ b/apps/examples/posix_spawn/filesystem/redirect/redirect.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * examples/posix_spawn/filesystem/program/program.c
+ * examples/posix_spawn/filesystem/redirect/redirect.c
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
@@ -47,6 +47,8 @@ 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.
*/
@@ -56,5 +58,6 @@ int main(int argc, char **argv)
putchar(ch);
}
+ printf("Exit-ing the stdin redirection test\n");
return 0;
}
diff --git a/apps/examples/posix_spawn/spawn_main.c b/apps/examples/posix_spawn/spawn_main.c
index 608145232..6f8859516 100644
--- a/apps/examples/posix_spawn/spawn_main.c
+++ b/apps/examples/posix_spawn/spawn_main.c
@@ -138,11 +138,15 @@ 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 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
****************************************************************************/
@@ -284,11 +288,87 @@ int spawn_main(int argc, char *argv[])
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
+ *************************************************************************/
+
/* Output a seperated so that we can clearly discriminate the output of
* this program from the others.
*/
- testheader(program);
+ testheader(g_redirect);
/* Initialize the attributes file actions structure */
@@ -297,12 +377,14 @@ int spawn_main(int argc, char *argv[])
{
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");
@@ -313,13 +395,15 @@ int spawn_main(int argc, char *argv[])
{
err("ERROR: posix_spawn_file_actions_addclose failed: %d\n", ret);
}
+ posix_spawn_file_actions_dump(&file_actions);
- snprintf(fullpath, 128, "%s/%s", MOUNTPT, data);
+ 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");
@@ -330,9 +414,9 @@ int spawn_main(int argc, char *argv[])
*/
#ifdef CONFIG_BINFMT_EXEPATH
- filepath = program;
+ filepath = g_redirect;
#else
- snprintf(fullpath, 128, "%s/%s", MOUNTPT, program);
+ snprintf(fullpath, 128, "%s/%s", MOUNTPT, g_redirect);
filepath = fullpath;
#endif
@@ -346,13 +430,29 @@ int spawn_main(int argc, char *argv[])
err("ERROR: posix_spawn failed: %d\n", ret);
}
- sleep(1);
+ 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 */
- (void)posix_spawn_file_actions_destroy(&file_actions);
- (void)posix_spawnattr_destroy(&attr);
elf_uninitialize();
mm_update(&g_mmstep, "End-of-Test");
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 7ddc4901e..63aac89f5 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -3905,4 +3905,6 @@
(from Max Holtzberg).
* configs/stm32f4discovery/posix_spawn: Added a configuration
that can be used for testing posix_spawn().
+ * arch/arm/src/stm32: Bring F1 support for general DMA and serial
+ DMA in paricular up to parity with F2/F4 (from Mike Smith).
diff --git a/nuttx/include/spawn.h b/nuttx/include/spawn.h
index 3978424fb..39ed9be15 100644
--- a/nuttx/include/spawn.h
+++ b/nuttx/include/spawn.h
@@ -61,7 +61,7 @@
#define POSIX_SPAWN_SETSCHEDPARAM (1 << 2) /* 1: Set task's priority */
#define POSIX_SPAWN_SETSCHEDULER (1 << 3) /* 1: Set task's scheduler policy */
#define POSIX_SPAWN_SETSIGDEF (1 << 4) /* 1: Set default signal actions */
-#define POSIX_SPAWN_SETSIGMASK (1 << 5) /* 1: Set sigmask *./
+#define POSIX_SPAWN_SETSIGMASK (1 << 5) /* 1: Set sigmask */
/****************************************************************************
* Type Definitions
@@ -181,6 +181,16 @@ int posix_spawnattr_setsigmask(FAR posix_spawnattr_t *attr,
# define posix_spawnattr_setsigmask(attr,sigmask) (ENOSYS)
#endif
+/* Non standard debug functions */
+
+#ifdef CONFIG_DEBUG
+void posix_spawn_file_actions_dump(FAR posix_spawn_file_actions_t *file_actions);
+void posix_spawnattr_dump(FAR posix_spawnattr_t *attr);
+#else
+# define posix_spawn_file_actions_dump(fa)
+# define posix_spawnattr_dump(a)
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/nuttx/libc/spawn/Make.defs b/nuttx/libc/spawn/Make.defs
index 2cf75c410..99ee781ce 100644
--- a/nuttx/libc/spawn/Make.defs
+++ b/nuttx/libc/spawn/Make.defs
@@ -42,6 +42,10 @@ CSRCS += lib_ps.c
CSRCS += lib_psfa_addaction.c lib_psfa_addclose.c lib_psfa_adddup2.c
CSRCS += lib_psfa_addopen.c lib_psfa_destroy.c lib_psfa_init.c
+ifeq ($(CONFIG_DEBUG),y)
+CSRCS += lib_psfa_dump.c
+endif
+
CSRCS += lib_psa_getflags.c lib_psa_getschedparam.c lib_psa_getschedpolicy.c
CSRCS += lib_psa_init.c lib_psa_setflags.c lib_psa_setschedparam.c
CSRCS += lib_psa_setschedpolicy.c
@@ -50,6 +54,10 @@ ifneq ($(CONFIG_DISABLE_SIGNALS),y)
CSRCS += lib_psa_getsigmask.c lib_psa_setsigmask.c
endif
+ifeq ($(CONFIG_DEBUG),y)
+CSRCS += lib_psa_dump.c
+endif
+
# Add the spawn directory to the build
DEPPATH += --dep-path spawn
diff --git a/nuttx/libc/spawn/lib_ps.c b/nuttx/libc/spawn/lib_ps.c
index 7509d6737..a6a0590d4 100644
--- a/nuttx/libc/spawn/lib_ps.c
+++ b/nuttx/libc/spawn/lib_ps.c
@@ -357,7 +357,7 @@ static int spawn_proxy(int argc, char *argv[])
{
FAR struct spawn_general_file_action_s *entry;
FAR const posix_spawnattr_t *attr = g_ps_parms.attr;
- int ret;
+ int ret = OK;
/* Perform file actions and/or set a custom signal mask. We get here only
* if the file_actions parameter to posix_spawn[p] was non-NULL and/or the
@@ -365,10 +365,10 @@ static int spawn_proxy(int argc, char *argv[])
*/
#ifndef CONFIG_DISABLE_SIGNALS
- DEBUGASSERT(g_ps_parms.file_actions ||
+ DEBUGASSERT((g_ps_parms.file_actions && *g_ps_parms.file_actions) ||
(attr && (attr->flags & POSIX_SPAWN_SETSIGMASK) != 0));
#else
- DEBUGASSERT(g_ps_parms.file_actions);
+ DEBUGASSERT(g_ps_parms.file_actions && *g_ps_parms.file_actions);
#endif
/* Check if we need to change the signal mask */
@@ -553,9 +553,10 @@ int posix_spawn(FAR pid_t *pid, FAR const char *path,
*/
#ifndef CONFIG_DISABLE_SIGNALS
- if (!file_actions && (attr->flags & POSIX_SPAWN_SETSIGMASK) == 0)
+ if ((file_actions == NULL || *file_actions == NULL) &&
+ (attr == NULL || (attr->flags & POSIX_SPAWN_SETSIGMASK) == 0))
#else
- if (!file_actions)
+ if (file_actions == NULL || *file_actions == NULL)
#endif
{
return ps_exec(pid, path, attr, argv);
@@ -601,7 +602,7 @@ int posix_spawn(FAR pid_t *pid, FAR const char *path,
proxy = TASK_CREATE("spawn_proxy", param.sched_priority,
CONFIG_POSIX_SPAWN_STACKSIZE, (main_t)spawn_proxy,
- (const char **)NULL);
+ (FAR const char **)NULL);
if (proxy < 0)
{
int errcode = errno;
diff --git a/nuttx/libc/spawn/lib_psa_dump.c b/nuttx/libc/spawn/lib_psa_dump.c
new file mode 100644
index 000000000..03770c6ff
--- /dev/null
+++ b/nuttx/libc/spawn/lib_psa_dump.c
@@ -0,0 +1,127 @@
+/****************************************************************************
+ * libc/string/lib_psa_dump.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 <spawn.h>
+#include <debug.h>
+
+#ifdef CONFIG_DEBUG
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: posix_spawnattr_dump
+ *
+ * Description:
+ * Show the current attributes.
+ *
+ * Input Parameters:
+ * attr - The address of the spawn attributes to be dumped.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void posix_spawnattr_dump(posix_spawnattr_t *attr)
+{
+ dbg("attr[%p]:\n", attr);
+ dbg(" flags: %04x\n", attr->flags);
+ if (attr->flags == 0)
+ {
+ dbg(" None\n");
+ }
+ else
+ {
+ if ((attr->flags & POSIX_SPAWN_RESETIDS) != 0)
+ {
+ dbg(" POSIX_SPAWN_RESETIDS\n");
+ }
+
+ if ((attr->flags & POSIX_SPAWN_SETPGROUP) != 0)
+ {
+ dbg(" POSIX_SPAWN_SETPGROUP\n");
+ }
+
+ if ((attr->flags & POSIX_SPAWN_SETSCHEDPARAM) != 0)
+ {
+ dbg(" POSIX_SPAWN_SETSCHEDPARAM\n");
+ }
+
+ if ((attr->flags & POSIX_SPAWN_SETSCHEDULER) != 0)
+ {
+ dbg(" POSIX_SPAWN_SETSCHEDULER\n");
+ }
+
+ if ((attr->flags & POSIX_SPAWN_SETSIGDEF) != 0)
+ {
+ dbg(" POSIX_SPAWN_SETSIGDEF\n");
+ }
+
+ if ((attr->flags & POSIX_SPAWN_SETSIGMASK) != 0)
+ {
+ dbg(" POSIX_SPAWN_SETSIGMASK\n");
+ }
+ }
+
+ dbg(" priority: %d\n", attr->priority);
+
+ dbg(" policy: %d\n", attr->policy);
+ if (attr->policy == SCHED_FIFO)
+ {
+ dbg(" SCHED_FIFO\n");
+ }
+ else if (attr->policy == SCHED_RR)
+ {
+ dbg(" SCHED_RR\n");
+ }
+ else
+ {
+ dbg(" Unrecognized\n");
+ }
+
+#ifndef CONFIG_DISABLE_SIGNALS
+ dbg(" sigmask: %08x\n", attr->sigmask);
+#endif
+};
+
+#endif /* CONFIG_DEBUG */ \ No newline at end of file
diff --git a/nuttx/libc/spawn/lib_psa_init.c b/nuttx/libc/spawn/lib_psa_init.c
index 8aabfd090..f76188c52 100644
--- a/nuttx/libc/spawn/lib_psa_init.c
+++ b/nuttx/libc/spawn/lib_psa_init.c
@@ -43,7 +43,6 @@
#include <spawn.h>
#include <assert.h>
#include <errno.h>
-#include <errno.h>
/****************************************************************************
* Global Functions
@@ -58,7 +57,7 @@
* call to posix_spawn() or posix_spawnp().
*
* Input Parameters:
- * attr - The address spawn attributes to be initialized.
+ * attr - The address of the spawn attributes to be initialized.
*
* Returned Value:
* On success, these functions return 0; on failure they return an error
diff --git a/nuttx/libc/spawn/lib_psfa_dump.c b/nuttx/libc/spawn/lib_psfa_dump.c
new file mode 100644
index 000000000..d7bf1576d
--- /dev/null
+++ b/nuttx/libc/spawn/lib_psfa_dump.c
@@ -0,0 +1,129 @@
+/****************************************************************************
+ * libc/string/lib_psfa_dump.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 <spawn.h>
+#include <assert.h>
+#include <debug.h>
+
+#include "spawn/spawn.h"
+
+#ifdef CONFIG_DEBUG
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lib_psfa_dump
+ *
+ * Description:
+ * Show the entryent file actions.
+ *
+ * Input Parameters:
+ * file_actions - The address of the file_actions to be dumped.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void posix_spawn_file_actions_dump(FAR posix_spawn_file_actions_t *file_actions)
+{
+ FAR struct spawn_general_file_action_s *entry;
+
+ DEBUGASSERT(file_actions);
+
+ dbg("File Actions[%p->%p]:\n", file_actions, *file_actions);
+ if (!*file_actions)
+ {
+ dbg(" NONE\n");
+ return;
+ }
+
+ /* Destroy each file action, one at a time */
+
+ for (entry = (FAR struct spawn_general_file_action_s *)*file_actions;
+ entry;
+ entry = entry->flink)
+ {
+ switch (entry->action)
+ {
+ case SPAWN_FILE_ACTION_CLOSE:
+ {
+ FAR struct spawn_close_file_action_s *action =
+ (FAR struct spawn_close_file_action_s *)entry;
+
+ dbg(" CLOSE: fd=%d\n", action->fd);
+ }
+ break;
+
+ case SPAWN_FILE_ACTION_DUP2:
+ {
+ FAR struct spawn_dup2_file_action_s *action =
+ (FAR struct spawn_dup2_file_action_s *)entry;
+
+ dbg(" DUP2: %d->%d\n", action->fd1, action->fd2);
+ }
+ break;
+
+ case SPAWN_FILE_ACTION_OPEN:
+ {
+ FAR struct spawn_open_file_action_s *action =
+ (FAR struct spawn_open_file_action_s *)entry;
+
+ svdbg(" OPEN: path=%s oflags=%04x mode=%04x fd=%d\n",
+ action->path, action->oflags, action->mode, action->fd);
+ }
+ break;
+
+ case SPAWN_FILE_ACTION_NONE:
+ default:
+ dbg(" ERROR: Unknown action: %d\n", entry->action);
+ break;
+ }
+ }
+}
+
+#endif /* CONFIG_DEBUG */ \ No newline at end of file
diff --git a/nuttx/sched/task_vfork.c b/nuttx/sched/task_vfork.c
index 64f6f0636..0ea09b048 100644
--- a/nuttx/sched/task_vfork.c
+++ b/nuttx/sched/task_vfork.c
@@ -218,6 +218,9 @@ pid_t task_vforkstart(FAR _TCB *child)
#endif
FAR const char *name;
pid_t pid;
+#ifdef CONFIG_SCHED_WAITPID
+ int rc;
+#endif
int ret;
svdbg("Starting Child TCB=%p, parent=%p\n", child, g_readytorun.head);
@@ -246,6 +249,64 @@ pid_t task_vforkstart(FAR _TCB *child)
return ERROR;
}
+ /* Since the child task has the same priority as the parent task, it is
+ * now ready to run, but has not yet ran. It is a requirement that
+ * the parent enivornment be stable while vfork runs; the child thread
+ * is still dependent on things in the parent thread... like the pointers
+ * into parent thread's stack which will still appear in the child's
+ * registers and environment.
+ *
+ * We do not have SIG_CHILD, so we have to do some silly things here.
+ * The simplest way to make sure that the child thread runs to completion
+ * is simply to yield here. Since the child can only do exit() or
+ * execv/l(), that should be all that is needed.
+ *
+ * Hmmm.. this is probably not sufficient. What if we are running
+ * SCHED_RR? What if the child thread is suspeneded and rescheduled
+ * after the parent thread again?
+ */
+
+#ifdef CONFIG_SCHED_WAITPID
+
+ /* We can also exploit a bug in the execv() implementation: The PID
+ * of the task exec'ed by the child will not be the same as the PID of
+ * the child task. Therefore, waitpid() on the child task's PID will
+ * accomplish what we need to do.
+ */
+
+ rc = 0;
+
+#ifdef CONFIG_DEBUG
+ ret = waitpid(pid, &rc, 0);
+ if (ret < 0)
+ {
+ sdbg("ERROR: waitpid failed: %d\n", errno);
+ }
+#else
+ (void)waitpid(pid, &rc, 0);
+#endif
+
+#else
+ /* Again exploiting that execv() bug: Check if the child thread is
+ * still running.
+ */
+
+ while ((ret = kill(pid, 0)) == OK)
+ {
+ /* Yes.. then we can yield to it -- assuming that it has not lowered
+ * its priority. sleep(0) might be a safer thing to do since it does
+ * not depend on prioirities: It will halt the parent thread for one
+ * system clock tick. This will delay the return to the parent thread.
+ */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+ sleep(0);
+#else
+ sched_yield();
+#endif
+ }
+#endif
+
return pid;
}