Split posix_spawn.c into 3 different files
posix_spawnattr.c
posix_spawn_file_actions.c
posix_spawn.c
Also, move the declarations of the posix_spawn types
into spawn.h.
These two changes combined allow alternative
implementations of posix_spawn to be provided without
duplicating the posix_spawnattr* and
posix_spawn_file_actions* functions.
BUG= https://code.google.com/p/nativeclient/issues/detail?id=3976
R=phosek@chromium.org
Review URL: https://codereview.chromium.org/650343002
diff --git a/newlib/libc/include/spawn.h b/newlib/libc/include/spawn.h
index 5a6692f..3d3067d 100644
--- a/newlib/libc/include/spawn.h
+++ b/newlib/libc/include/spawn.h
@@ -28,16 +28,49 @@
#define _SPAWN_H_
#include <_ansi.h>
+#include <sched.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/_types.h>
+#include <sys/queue.h>
#define __need_sigset_t
#include <signal.h>
struct sched_param;
-typedef struct __posix_spawnattr *posix_spawnattr_t;
-typedef struct __posix_spawn_file_actions *posix_spawn_file_actions_t;
+typedef struct {
+ short sa_flags;
+ pid_t sa_pgroup;
+ struct sched_param sa_schedparam;
+ int sa_schedpolicy;
+ sigset_t sa_sigdefault;
+ sigset_t sa_sigmask;
+} posix_spawnattr_t;
+
+typedef struct __posix_spawn_file_actions_entry {
+ STAILQ_ENTRY(__posix_spawn_file_actions_entry) fae_list;
+ enum { FAE_OPEN, FAE_DUP2, FAE_CLOSE } fae_action;
+
+ int fae_fildes;
+ union {
+ struct {
+ char *path;
+#define fae_path fae_data.open.path
+ int oflag;
+#define fae_oflag fae_data.open.oflag
+ mode_t mode;
+#define fae_mode fae_data.open.mode
+ } open;
+ struct {
+ int newfildes;
+#define fae_newfildes fae_data.dup2.newfildes
+ } dup2;
+ } fae_data;
+} posix_spawn_file_actions_entry_t;
+
+typedef struct {
+ STAILQ_HEAD(, __posix_spawn_file_actions_entry) fa_list;
+} posix_spawn_file_actions_t;
#define POSIX_SPAWN_RESETIDS 0x01
#define POSIX_SPAWN_SETPGROUP 0x02
diff --git a/newlib/libc/posix/Makefile.am b/newlib/libc/posix/Makefile.am
index aca993e..5ec6b76 100644
--- a/newlib/libc/posix/Makefile.am
+++ b/newlib/libc/posix/Makefile.am
@@ -20,7 +20,7 @@
execve.c execvp.c wordexp.c wordfree.c
ELIX_4_SOURCES = \
- popen.c posix_spawn.c
+ popen.c posix_spawn.c posix_spawnaddr.c posix_spawn_file_actions.c
if ELIX_LEVEL_1
ELIX_SOURCES =
diff --git a/newlib/libc/posix/Makefile.in b/newlib/libc/posix/Makefile.in
index 81ba815..6dec1f8 100644
--- a/newlib/libc/posix/Makefile.in
+++ b/newlib/libc/posix/Makefile.in
@@ -87,7 +87,7 @@
lib_a-execlp.$(OBJEXT) lib_a-execv.$(OBJEXT) \
lib_a-execve.$(OBJEXT) lib_a-execvp.$(OBJEXT) \
lib_a-wordexp.$(OBJEXT) lib_a-wordfree.$(OBJEXT)
-am__objects_4 = lib_a-popen.$(OBJEXT) lib_a-posix_spawn.$(OBJEXT)
+am__objects_4 = lib_a-popen.$(OBJEXT) lib_a-posix_spawn.$(OBJEXT) lib_a-posix_spawnattr.$(OBJEXT) lib_a-posix_spawn_file_actions.$(OBJEXT)
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_5 = $(am__objects_2) \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ $(am__objects_3) \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ $(am__objects_4)
@@ -305,7 +305,7 @@
execve.c execvp.c wordexp.c wordfree.c
ELIX_4_SOURCES = \
- popen.c posix_spawn.c
+ popen.c posix_spawn.c posix_spawnattr.c posix_spawn_file_actions.c
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ELIX_SOURCES = $(ELIX_2_SOURCES) $(ELIX_3_SOURCES) $(ELIX_4_SOURCES)
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@ELIX_SOURCES = $(ELIX_2_SOURCES) $(ELIX_3_SOURCES)
@@ -582,6 +582,18 @@
lib_a-posix_spawn.obj: posix_spawn.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-posix_spawn.obj `if test -f 'posix_spawn.c'; then $(CYGPATH_W) 'posix_spawn.c'; else $(CYGPATH_W) '$(srcdir)/posix_spawn.c'; fi`
+lib_a-posix_spawnattr.o: posix_spawnattr.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-posix_spawnattr.o `test -f 'posix_spawnattr.c' || echo '$(srcdir)/'`posix_spawnattr.c
+
+lib_a-posix_spawnattr.obj: posix_spawnattr.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-posix_spawnattr.obj `if test -f 'posix_spawnattr.c'; then $(CYGPATH_W) 'posix_spawnattr.c'; else $(CYGPATH_W) '$(srcdir)/posix_spawnattr.c'; fi`
+
+lib_a-posix_spawn_file_actions.o: posix_spawn_file_actions.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-posix_spawn_file_actions.o `test -f 'posix_spawn_file_actions.c' || echo '$(srcdir)/'`posix_spawn_file_actions.c
+
+lib_a-posix_spawn_file_actions.obj: posix_spawn_file_actions.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-posix_spawn_file_actions.obj `if test -f 'posix_spawn_file_actions.c'; then $(CYGPATH_W) 'posix_spawn_file_actions.c'; else $(CYGPATH_W) '$(srcdir)/posix_spawn_file_actions.c'; fi`
+
mostlyclean-libtool:
-rm -f *.lo
diff --git a/newlib/libc/posix/posix_spawn.c b/newlib/libc/posix/posix_spawn.c
index bc0e033..7f13c71 100644
--- a/newlib/libc/posix/posix_spawn.c
+++ b/newlib/libc/posix/posix_spawn.c
@@ -91,13 +91,11 @@
#include <sys/cdefs.h>
#include <sys/signal.h>
-#include <sys/queue.h>
#include <sys/wait.h>
#include <_syslist.h>
#include <errno.h>
#include <fcntl.h>
-#include <sched.h>
#include <spawn.h>
#include <signal.h>
#include <stdlib.h>
@@ -109,46 +107,12 @@
'environ'. */
static char ***p_environ = &environ;
-struct __posix_spawnattr {
- short sa_flags;
- pid_t sa_pgroup;
- struct sched_param sa_schedparam;
- int sa_schedpolicy;
- sigset_t sa_sigdefault;
- sigset_t sa_sigmask;
-};
-
-struct __posix_spawn_file_actions {
- STAILQ_HEAD(, __posix_spawn_file_actions_entry) fa_list;
-};
-
-typedef struct __posix_spawn_file_actions_entry {
- STAILQ_ENTRY(__posix_spawn_file_actions_entry) fae_list;
- enum { FAE_OPEN, FAE_DUP2, FAE_CLOSE } fae_action;
-
- int fae_fildes;
- union {
- struct {
- char *path;
-#define fae_path fae_data.open.path
- int oflag;
-#define fae_oflag fae_data.open.oflag
- mode_t mode;
-#define fae_mode fae_data.open.mode
- } open;
- struct {
- int newfildes;
-#define fae_newfildes fae_data.dup2.newfildes
- } dup2;
- } fae_data;
-} posix_spawn_file_actions_entry_t;
-
/*
* Spawn routines
*/
static int
-process_spawnattr(_CONST posix_spawnattr_t sa)
+process_spawnattr(_CONST posix_spawnattr_t* sa)
{
struct sigaction sigact = { .sa_flags = 0, .sa_handler = SIG_DFL };
int i;
@@ -241,7 +205,7 @@
}
static int
-process_file_actions(_CONST posix_spawn_file_actions_t fa)
+process_file_actions(_CONST posix_spawn_file_actions_t* fa)
{
posix_spawn_file_actions_entry_t *fae;
int error;
@@ -270,12 +234,12 @@
return (errno);
case 0:
if (sa != NULL) {
- error = process_spawnattr(*sa);
+ error = process_spawnattr(sa);
if (error)
_exit(127);
}
if (fa != NULL) {
- error = process_file_actions(*fa);
+ error = process_file_actions(fa);
if (error)
_exit(127);
}
@@ -318,261 +282,4 @@
return do_posix_spawn(pid, path, fa, sa, argv, envp, 1);
}
-/*
- * File descriptor actions
- */
-
-int
-_DEFUN(posix_spawn_file_actions_init, (ret),
- posix_spawn_file_actions_t *ret)
-{
- posix_spawn_file_actions_t fa;
-
- fa = malloc(sizeof(struct __posix_spawn_file_actions));
- if (fa == NULL)
- return (-1);
-
- STAILQ_INIT(&fa->fa_list);
- *ret = fa;
- return (0);
-}
-
-int
-_DEFUN(posix_spawn_file_actions_destroy, (fa),
- posix_spawn_file_actions_t *fa)
-{
- posix_spawn_file_actions_entry_t *fae;
-
- while ((fae = STAILQ_FIRST(&(*fa)->fa_list)) != NULL) {
- /* Remove file action entry from the queue */
- STAILQ_REMOVE_HEAD(&(*fa)->fa_list, fae_list);
-
- /* Deallocate file action entry */
- if (fae->fae_action == FAE_OPEN)
- free(fae->fae_path);
- free(fae);
- }
-
- free(*fa);
- return (0);
-}
-
-int
-_DEFUN(posix_spawn_file_actions_addopen, (fa, fildes, path, oflag, mode),
- posix_spawn_file_actions_t * __restrict fa _AND
- int fildes _AND
- _CONST char * __restrict path _AND
- int oflag _AND
- mode_t mode)
-{
- posix_spawn_file_actions_entry_t *fae;
- int error;
-
- if (fildes < 0)
- return (EBADF);
-
- /* Allocate object */
- fae = malloc(sizeof(posix_spawn_file_actions_entry_t));
- if (fae == NULL)
- return (errno);
-
- /* Set values and store in queue */
- fae->fae_action = FAE_OPEN;
- fae->fae_path = strdup(path);
- if (fae->fae_path == NULL) {
- error = errno;
- free(fae);
- return (error);
- }
- fae->fae_fildes = fildes;
- fae->fae_oflag = oflag;
- fae->fae_mode = mode;
-
- STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list);
- return (0);
-}
-
-int
-_DEFUN(posix_spawn_file_actions_adddup2, (fa, fildes, newfildes),
- posix_spawn_file_actions_t *fa _AND
- int fildes _AND
- int newfildes)
-{
- posix_spawn_file_actions_entry_t *fae;
-
- if (fildes < 0 || newfildes < 0)
- return (EBADF);
-
- /* Allocate object */
- fae = malloc(sizeof(posix_spawn_file_actions_entry_t));
- if (fae == NULL)
- return (errno);
-
- /* Set values and store in queue */
- fae->fae_action = FAE_DUP2;
- fae->fae_fildes = fildes;
- fae->fae_newfildes = newfildes;
-
- STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list);
- return (0);
-}
-
-int
-_DEFUN(posix_spawn_file_actions_addclose, (fa, fildes),
- posix_spawn_file_actions_t *fa _AND
- int fildes)
-{
- posix_spawn_file_actions_entry_t *fae;
-
- if (fildes < 0)
- return (EBADF);
-
- /* Allocate object */
- fae = malloc(sizeof(posix_spawn_file_actions_entry_t));
- if (fae == NULL)
- return (errno);
-
- /* Set values and store in queue */
- fae->fae_action = FAE_CLOSE;
- fae->fae_fildes = fildes;
-
- STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list);
- return (0);
-}
-
-/*
- * Spawn attributes
- */
-
-int
-_DEFUN(posix_spawnattr_init, (ret),
- posix_spawnattr_t *ret)
-{
- posix_spawnattr_t sa;
-
- sa = calloc(1, sizeof(struct __posix_spawnattr));
- if (sa == NULL)
- return (errno);
-
- /* Set defaults as specified by POSIX, cleared above */
- *ret = sa;
- return (0);
-}
-
-int
-_DEFUN(posix_spawnattr_destroy, (sa),
- posix_spawnattr_t *sa)
-{
- free(*sa);
- return (0);
-}
-
-int
-_DEFUN(posix_spawnattr_getflags, (sa, flags),
- _CONST posix_spawnattr_t * __restrict sa _AND
- short * __restrict flags)
-{
- *flags = (*sa)->sa_flags;
- return (0);
-}
-
-int
-_DEFUN(posix_spawnattr_getpgroup, (sa, pgroup),
- _CONST posix_spawnattr_t * __restrict sa _AND
- pid_t * __restrict pgroup)
-{
- *pgroup = (*sa)->sa_pgroup;
- return (0);
-}
-
-int
-_DEFUN(posix_spawnattr_getschedparam, (sa, schedparam),
- _CONST posix_spawnattr_t * __restrict sa _AND
- struct sched_param * __restrict schedparam)
-{
- *schedparam = (*sa)->sa_schedparam;
- return (0);
-}
-
-int
-_DEFUN(posix_spawnattr_getschedpolicy, (sa, schedpolicy),
- _CONST posix_spawnattr_t * __restrict sa _AND
- int * __restrict schedpolicy)
-{
- *schedpolicy = (*sa)->sa_schedpolicy;
- return (0);
-}
-
-int
-_DEFUN(posix_spawnattr_getsigdefault, (sa, sigdefault),
- _CONST posix_spawnattr_t * __restrict sa _AND
- sigset_t * __restrict sigdefault)
-{
- *sigdefault = (*sa)->sa_sigdefault;
- return (0);
-}
-
-int
-_DEFUN(posix_spawnattr_getsigmask, (sa, sigmask),
- _CONST posix_spawnattr_t * __restrict sa _AND
- sigset_t * __restrict sigmask)
-{
- *sigmask = (*sa)->sa_sigmask;
- return (0);
-}
-
-int
-_DEFUN(posix_spawnattr_setflags, (sa, flags),
- posix_spawnattr_t *sa _AND
- short flags)
-{
- (*sa)->sa_flags = flags;
- return (0);
-}
-
-int
-_DEFUN(posix_spawnattr_setpgroup, (sa, pgroup),
- posix_spawnattr_t *sa _AND
- pid_t pgroup)
-{
- (*sa)->sa_pgroup = pgroup;
- return (0);
-}
-
-int
-_DEFUN(posix_spawnattr_setschedparam, (sa, schedparam),
- posix_spawnattr_t * __restrict sa _AND
- _CONST struct sched_param * __restrict schedparam)
-{
- (*sa)->sa_schedparam = *schedparam;
- return (0);
-}
-
-int
-_DEFUN(posix_spawnattr_setschedpolicy, (sa, schedpolicy),
- posix_spawnattr_t *sa _AND
- int schedpolicy)
-{
- (*sa)->sa_schedpolicy = schedpolicy;
- return (0);
-}
-
-int
-_DEFUN(posix_spawnattr_setsigdefault, (sa, sigdefault),
- posix_spawnattr_t * __restrict sa _AND
- _CONST sigset_t * __restrict sigdefault)
-{
- (*sa)->sa_sigdefault = *sigdefault;
- return (0);
-}
-
-int
-_DEFUN(posix_spawnattr_setsigmask, (sa, sigmask),
- posix_spawnattr_t * __restrict sa _AND
- _CONST sigset_t * __restrict sigmask)
-{
- (*sa)->sa_sigmask = *sigmask;
- return (0);
-}
-
#endif /* !_NO_POSIX_SPAWN */
diff --git a/newlib/libc/posix/posix_spawn_file_actions.c b/newlib/libc/posix/posix_spawn_file_actions.c
new file mode 100644
index 0000000..bfa7ce0
--- /dev/null
+++ b/newlib/libc/posix/posix_spawn_file_actions.c
@@ -0,0 +1,158 @@
+/*-
+ * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ */
+
+#ifndef _NO_POSIX_SPAWN
+
+#include <sys/cdefs.h>
+
+#include <errno.h>
+#include <spawn.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * File descriptor actions
+ */
+
+int
+_DEFUN(posix_spawn_file_actions_init, (ret),
+ posix_spawn_file_actions_t *ret)
+{
+ posix_spawn_file_actions_t* fa;
+
+ fa = malloc(sizeof(posix_spawn_file_actions_t));
+ if (fa == NULL)
+ return (-1);
+
+ STAILQ_INIT(&fa->fa_list);
+ ret = fa;
+ return (0);
+}
+
+int
+_DEFUN(posix_spawn_file_actions_destroy, (fa),
+ posix_spawn_file_actions_t *fa)
+{
+ posix_spawn_file_actions_entry_t *fae;
+
+ while ((fae = STAILQ_FIRST(&fa->fa_list)) != NULL) {
+ /* Remove file action entry from the queue */
+ STAILQ_REMOVE_HEAD(&fa->fa_list, fae_list);
+
+ /* Deallocate file action entry */
+ if (fae->fae_action == FAE_OPEN)
+ free(fae->fae_path);
+ free(fae);
+ }
+
+ free(fa);
+ return (0);
+}
+
+int
+_DEFUN(posix_spawn_file_actions_addopen, (fa, fildes, path, oflag, mode),
+ posix_spawn_file_actions_t * __restrict fa _AND
+ int fildes _AND
+ _CONST char * __restrict path _AND
+ int oflag _AND
+ mode_t mode)
+{
+ posix_spawn_file_actions_entry_t *fae;
+ int error;
+
+ if (fildes < 0)
+ return (EBADF);
+
+ /* Allocate object */
+ fae = malloc(sizeof(posix_spawn_file_actions_entry_t));
+ if (fae == NULL)
+ return (errno);
+
+ /* Set values and store in queue */
+ fae->fae_action = FAE_OPEN;
+ fae->fae_path = strdup(path);
+ if (fae->fae_path == NULL) {
+ error = errno;
+ free(fae);
+ return (error);
+ }
+ fae->fae_fildes = fildes;
+ fae->fae_oflag = oflag;
+ fae->fae_mode = mode;
+
+ STAILQ_INSERT_TAIL(&fa->fa_list, fae, fae_list);
+ return (0);
+}
+
+int
+_DEFUN(posix_spawn_file_actions_adddup2, (fa, fildes, newfildes),
+ posix_spawn_file_actions_t *fa _AND
+ int fildes _AND
+ int newfildes)
+{
+ posix_spawn_file_actions_entry_t *fae;
+
+ if (fildes < 0 || newfildes < 0)
+ return (EBADF);
+
+ /* Allocate object */
+ fae = malloc(sizeof(posix_spawn_file_actions_entry_t));
+ if (fae == NULL)
+ return (errno);
+
+ /* Set values and store in queue */
+ fae->fae_action = FAE_DUP2;
+ fae->fae_fildes = fildes;
+ fae->fae_newfildes = newfildes;
+
+ STAILQ_INSERT_TAIL(&fa->fa_list, fae, fae_list);
+ return (0);
+}
+
+int
+_DEFUN(posix_spawn_file_actions_addclose, (fa, fildes),
+ posix_spawn_file_actions_t *fa _AND
+ int fildes)
+{
+ posix_spawn_file_actions_entry_t *fae;
+
+ if (fildes < 0)
+ return (EBADF);
+
+ /* Allocate object */
+ fae = malloc(sizeof(posix_spawn_file_actions_entry_t));
+ if (fae == NULL)
+ return (errno);
+
+ /* Set values and store in queue */
+ fae->fae_action = FAE_CLOSE;
+ fae->fae_fildes = fildes;
+
+ STAILQ_INSERT_TAIL(&fa->fa_list, fae, fae_list);
+ return (0);
+}
+
+#endif /* !_NO_POSIX_SPAWN */
diff --git a/newlib/libc/posix/posix_spawnattr.c b/newlib/libc/posix/posix_spawnattr.c
new file mode 100644
index 0000000..1eb6ee8
--- /dev/null
+++ b/newlib/libc/posix/posix_spawnattr.c
@@ -0,0 +1,168 @@
+/*-
+ * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ */
+
+#ifndef _NO_POSIX_SPAWN
+
+#include <errno.h>
+#include <spawn.h>
+#include <stdlib.h>
+
+/*
+ * Spawn attributes
+ */
+
+int
+_DEFUN(posix_spawnattr_init, (ret),
+ posix_spawnattr_t *ret)
+{
+ posix_spawnattr_t* sa;
+
+ sa = calloc(1, sizeof(posix_spawnattr_t));
+ if (sa == NULL)
+ return (errno);
+
+ /* Set defaults as specified by POSIX, cleared above */
+ ret = sa;
+ return (0);
+}
+
+int
+_DEFUN(posix_spawnattr_destroy, (sa),
+ posix_spawnattr_t *sa)
+{
+ free(sa);
+ return (0);
+}
+
+int
+_DEFUN(posix_spawnattr_getflags, (sa, flags),
+ _CONST posix_spawnattr_t * __restrict sa _AND
+ short * __restrict flags)
+{
+ *flags = sa->sa_flags;
+ return (0);
+}
+
+int
+_DEFUN(posix_spawnattr_getpgroup, (sa, pgroup),
+ _CONST posix_spawnattr_t * __restrict sa _AND
+ pid_t * __restrict pgroup)
+{
+ *pgroup = sa->sa_pgroup;
+ return (0);
+}
+
+int
+_DEFUN(posix_spawnattr_getschedparam, (sa, schedparam),
+ _CONST posix_spawnattr_t * __restrict sa _AND
+ struct sched_param * __restrict schedparam)
+{
+ *schedparam = sa->sa_schedparam;
+ return (0);
+}
+
+int
+_DEFUN(posix_spawnattr_getschedpolicy, (sa, schedpolicy),
+ _CONST posix_spawnattr_t * __restrict sa _AND
+ int * __restrict schedpolicy)
+{
+ *schedpolicy = sa->sa_schedpolicy;
+ return (0);
+}
+
+int
+_DEFUN(posix_spawnattr_getsigdefault, (sa, sigdefault),
+ _CONST posix_spawnattr_t * __restrict sa _AND
+ sigset_t * __restrict sigdefault)
+{
+ *sigdefault = sa->sa_sigdefault;
+ return (0);
+}
+
+int
+_DEFUN(posix_spawnattr_getsigmask, (sa, sigmask),
+ _CONST posix_spawnattr_t * __restrict sa _AND
+ sigset_t * __restrict sigmask)
+{
+ *sigmask = sa->sa_sigmask;
+ return (0);
+}
+
+int
+_DEFUN(posix_spawnattr_setflags, (sa, flags),
+ posix_spawnattr_t *sa _AND
+ short flags)
+{
+ sa->sa_flags = flags;
+ return (0);
+}
+
+int
+_DEFUN(posix_spawnattr_setpgroup, (sa, pgroup),
+ posix_spawnattr_t *sa _AND
+ pid_t pgroup)
+{
+ sa->sa_pgroup = pgroup;
+ return (0);
+}
+
+int
+_DEFUN(posix_spawnattr_setschedparam, (sa, schedparam),
+ posix_spawnattr_t * __restrict sa _AND
+ _CONST struct sched_param * __restrict schedparam)
+{
+ sa->sa_schedparam = *schedparam;
+ return (0);
+}
+
+int
+_DEFUN(posix_spawnattr_setschedpolicy, (sa, schedpolicy),
+ posix_spawnattr_t *sa _AND
+ int schedpolicy)
+{
+ sa->sa_schedpolicy = schedpolicy;
+ return (0);
+}
+
+int
+_DEFUN(posix_spawnattr_setsigdefault, (sa, sigdefault),
+ posix_spawnattr_t * __restrict sa _AND
+ _CONST sigset_t * __restrict sigdefault)
+{
+ sa->sa_sigdefault = *sigdefault;
+ return (0);
+}
+
+int
+_DEFUN(posix_spawnattr_setsigmask, (sa, sigmask),
+ posix_spawnattr_t * __restrict sa _AND
+ _CONST sigset_t * __restrict sigmask)
+{
+ sa->sa_sigmask = *sigmask;
+ return (0);
+}
+
+#endif /* !_NO_POSIX_SPAWN */