This will allow checking for and optimizing cases that can easily be
implemented using ch_spawn instead of using a full fork/exec.
---
winsup/cygwin/cygwin.din | 4 +--
winsup/cygwin/spawn.cc | 70 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index d7a17b234a..3f21d6899e 100644
--- a/winsup/cygwin/cygwin.din
+++ b/winsup/cygwin/cygwin.din
@@ -1058,7 +1058,7 @@ posix_getdents SIGFE
posix_madvise SIGFE
posix_memalign SIGFE
posix_openpt SIGFE
-posix_spawn SIGFE
+posix_spawn = cygwin_posix_spawn SIGFE
posix_spawn_file_actions_addchdir = posix_spawn_file_actions_addchdir_np SIGFE
posix_spawn_file_actions_addchdir_np SIGFE
posix_spawn_file_actions_addclose SIGFE
@@ -1082,7 +1082,7 @@ posix_spawnattr_setschedparam NOSIGFE
posix_spawnattr_setschedpolicy NOSIGFE
posix_spawnattr_setsigdefault NOSIGFE
posix_spawnattr_setsigmask NOSIGFE
-posix_spawnp SIGFE
+posix_spawnp = cygwin_posix_spawnp SIGFE
pow NOSIGFE
pow10 NOSIGFE
pow10f NOSIGFE
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 9a7f0bbf73..dc5f04db98 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -10,6 +10,8 @@ details. */
#include <stdlib.h>
#include <unistd.h>
#include <process.h>
+#include <spawn.h>
+#include <sys/queue.h>
#include <sys/wait.h>
#include <wchar.h>
#include <ctype.h>
@@ -1376,3 +1378,71 @@ __posix_spawn_execvpe (const char *path, char * const
*argv, char *const *envp,
__posix_spawn_sem_release (sem, errno);
return -1;
}
+
+/* HACK: duplicate some structs from newlib/libc/posix/posix_spawn.c */
+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;
+
+static int
+do_posix_spawn (pid_t *pid, const char *path,
+ const posix_spawn_file_actions_t *fa,
+ const posix_spawnattr_t *sa, char * const argv[],
+ char * const envp[], int use_env_path)
+{
+ syscall_printf ("posix_spawn%s (%p, %s, %p, %p, %p, %p)",
+ use_env_path ? "p" : "", pid, path, fa, sa, argv, envp);
+ if (use_env_path)
+ return posix_spawnp (pid, path, fa, sa, argv, envp);
+ else
+ return posix_spawn (pid, path, fa, sa, argv, envp);
+}
+
+extern "C" int
+cygwin_posix_spawn (pid_t *pid, const char *path,
+ const posix_spawn_file_actions_t *fa,
+ const posix_spawnattr_t *sa, char * const argv[],
+ char * const envp[])
+{
+ return do_posix_spawn (pid, path, fa, sa, argv, envp, 0);
+}
+
+extern "C" int
+cygwin_posix_spawnp (pid_t *pid, const char *path,
+ const posix_spawn_file_actions_t *fa,
+ const posix_spawnattr_t *sa, char * const argv[],
+ char * const envp[])
+{
+ return do_posix_spawn (pid, path, fa, sa, argv, envp, 1);
+}
--
2.49.0.windows.1