diff options
Diffstat (limited to 'newlib/libc/posix/posix_spawn.c')
-rw-r--r-- | newlib/libc/posix/posix_spawn.c | 59 |
1 files changed, 12 insertions, 47 deletions
diff --git a/newlib/libc/posix/posix_spawn.c b/newlib/libc/posix/posix_spawn.c index 46e4e53..f63b3af 100644 --- a/newlib/libc/posix/posix_spawn.c +++ b/newlib/libc/posix/posix_spawn.c @@ -102,56 +102,13 @@ Supporting OS subroutines required: <<_close>>, <<dup2>>, <<_fcntl>>, #include <stdlib.h> #include <string.h> #include <unistd.h> +#include "posix_spawn.h" /* Only deal with a pointer to environ, to work around subtle bugs with shared libraries and/or small data systems where the user declares his own '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_CHDIR, - FAE_FCHDIR - } 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; - char *dir; -#define fae_dir fae_data.dir - int dirfd; -#define fae_dirfd fae_data.dirfd - } fae_data; -} posix_spawn_file_actions_entry_t; - /* * Spawn routines */ @@ -222,23 +179,31 @@ process_file_actions_entry(posix_spawn_file_actions_entry_t *fae) if (fd < 0) return (errno); if (fd != fae->fae_fildes) { +#ifdef HAVE_FCNTL + int fdflags = _fcntl(fd, F_GETFD); + if (fdflags == -1) + return (errno); +#endif if (dup2(fd, fae->fae_fildes) == -1) return (errno); if (_close(fd) != 0) { if (errno == EBADF) return (EBADF); } - } #ifdef HAVE_FCNTL - if (_fcntl(fae->fae_fildes, F_SETFD, 0) == -1) - return (errno); + if (_fcntl(fae->fae_fildes, F_SETFD, fdflags) == -1) + return (errno); #endif /* HAVE_FCNTL */ + } break; case FAE_DUP2: /* Perform a dup2() */ if (dup2(fae->fae_fildes, fae->fae_newfildes) == -1) return (errno); #ifdef HAVE_FCNTL + /* This is necessary because POSIX says the FD_CLOEXEC flag + * must be clear, even though dup2 is specified to not clear + * the FD_CLOEXEC flag if the two file descriptors are equal */ if (_fcntl(fae->fae_newfildes, F_SETFD, 0) == -1) return (errno); #endif /* HAVE_FCNTL */ |