From 8e578ea68fa570aa46f04d4cf1c593ac11732bdf Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Wed, 17 Apr 2019 16:44:05 -0700 Subject: [PATCH] libiberty: Implement pex_unix_exec_child using posix_spawn --- libiberty/config.in | 6 +++ libiberty/configure | 10 ++--- libiberty/configure.ac | 10 ++--- libiberty/pex-unix.c | 95 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 110 insertions(+), 11 deletions(-) diff --git a/libiberty/config.in b/libiberty/config.in index f7052b5d958..ce79a9e77f2 100644 --- a/libiberty/config.in +++ b/libiberty/config.in @@ -198,6 +198,9 @@ /* Define to 1 if you have the `pipe2' function. */ #undef HAVE_PIPE2 +/* Define to 1 if you have the `posix_spawn' function. */ +#undef HAVE_POSIX_SPAWN + /* Define to 1 if you have the header file. */ #undef HAVE_PROCESS_H @@ -249,6 +252,9 @@ /* Define to 1 if you have the `spawnvpe' function. */ #undef HAVE_SPAWNVPE +/* Define to 1 if you have the header file. */ +#undef HAVE_SPAWN_H + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H diff --git a/libiberty/configure b/libiberty/configure index 306c07bd37e..6f85b1fd529 100755 --- a/libiberty/configure +++ b/libiberty/configure @@ -5652,7 +5652,7 @@ host_makefile_frag=${frag} # It's OK to check for header files. Although the compiler may not be # able to link anything, it had better be able to at least compile # something. -for ac_header in sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h stdio_ext.h process.h sys/prctl.h +for ac_header in sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h stdio_ext.h process.h sys/prctl.h spawn.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_preproc "$LINENO" "$ac_header" "$as_ac_Header" @@ -6161,9 +6161,9 @@ funcs="$funcs setproctitle" vars="sys_errlist sys_nerr sys_siglist" checkfuncs="__fsetlocking canonicalize_file_name dup3 getrlimit getrusage \ - getsysinfo gettimeofday on_exit pipe2 psignal pstat_getdynamic pstat_getstatic \ - realpath setrlimit spawnve spawnvpe strerror strsignal sysconf sysctl \ - sysmp table times wait3 wait4" + getsysinfo gettimeofday on_exit pipe2 posix_spawn psignal pstat_getdynamic \ + pstat_getstatic realpath setrlimit spawnve spawnvpe strerror strsignal \ + sysconf sysctl sysmp table times wait3 wait4" # Darwin has sbrk, but it is deprecated and that produces build-time warnings # so do not check for it. @@ -6184,7 +6184,7 @@ if test "x" = "y"; then index insque \ memchr memcmp memcpy memmem memmove memset mkstemps \ on_exit \ - pipe2 psignal pstat_getdynamic pstat_getstatic putenv \ + pipe2 posix_spawn psignal pstat_getdynamic pstat_getstatic putenv \ random realpath rename rindex \ sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \ stpcpy stpncpy strcasecmp strchr strdup \ diff --git a/libiberty/configure.ac b/libiberty/configure.ac index 6c1ff9c6093..5d21f383e7d 100644 --- a/libiberty/configure.ac +++ b/libiberty/configure.ac @@ -289,7 +289,7 @@ AC_SUBST_FILE(host_makefile_frag) # It's OK to check for header files. Although the compiler may not be # able to link anything, it had better be able to at least compile # something. -AC_CHECK_HEADERS(sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h stdio_ext.h process.h sys/prctl.h) +AC_CHECK_HEADERS(sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h stdio_ext.h process.h sys/prctl.h spawn.h) AC_HEADER_SYS_WAIT AC_HEADER_TIME @@ -412,9 +412,9 @@ funcs="$funcs setproctitle" vars="sys_errlist sys_nerr sys_siglist" checkfuncs="__fsetlocking canonicalize_file_name dup3 getrlimit getrusage \ - getsysinfo gettimeofday on_exit pipe2 psignal pstat_getdynamic pstat_getstatic \ - realpath setrlimit spawnve spawnvpe strerror strsignal sysconf sysctl \ - sysmp table times wait3 wait4" + getsysinfo gettimeofday on_exit pipe2 posix_spawn psignal pstat_getdynamic \ + pstat_getstatic realpath setrlimit spawnve spawnvpe strerror strsignal \ + sysconf sysctl sysmp table times wait3 wait4" # Darwin has sbrk, but it is deprecated and that produces build-time warnings # so do not check for it. @@ -435,7 +435,7 @@ if test "x" = "y"; then index insque \ memchr memcmp memcpy memmem memmove memset mkstemps \ on_exit \ - pipe2 psignal pstat_getdynamic pstat_getstatic putenv \ + pipe2 posix_spawn psignal pstat_getdynamic pstat_getstatic putenv \ random realpath rename rindex \ sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \ stpcpy stpncpy strcasecmp strchr strdup \ diff --git a/libiberty/pex-unix.c b/libiberty/pex-unix.c index 850d344ba58..ba3a6d5d38f 100644 --- a/libiberty/pex-unix.c +++ b/libiberty/pex-unix.c @@ -58,6 +58,9 @@ extern int errno; #ifdef HAVE_PROCESS_H #include #endif +#ifdef HAVE_SPAWN_H +#include +#endif #ifdef vfork /* Autoconf may define this to fork for us. */ # define VFORK_STRING "fork" @@ -366,7 +369,97 @@ pex_unix_close (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd) /* Execute a child. */ -#if defined(HAVE_SPAWNVE) && defined(HAVE_SPAWNVPE) +#if defined(HAVE_POSIX_SPAWN) +/* Implementation of pex->exec_child using the posix_spawn operation. */ + +static pid_t +pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable, + char * const * argv, char * const * env, + int in, int out, int errdes, + int toclose, const char **errmsg, int *err) +{ + posix_spawn_file_actions_t file_actions; + pid_t pid; + int ret; + + *errmsg = "posix_spawn"; + ret = posix_spawn_file_actions_init (&file_actions); + if (ret != 0) + goto error; + if (in != STDIN_FILE_NO) + { + ret = posix_spawn_file_actions_adddup2 (&file_actions, in, STDIN_FILE_NO); + if (ret != 0) + goto error; + ret = posix_spawn_file_actions_addclose (&file_actions, in); + if (ret != 0) + goto error; + } + if (out != STDOUT_FILE_NO) + { + ret = posix_spawn_file_actions_adddup2 (&file_actions, out, STDOUT_FILE_NO); + if (ret != 0) + goto error; + ret = posix_spawn_file_actions_addclose (&file_actions, out); + if (ret != 0) + goto error; + } + if ((flags & PEX_STDERR_TO_STDOUT) != 0) + { + ret = posix_spawn_file_actions_adddup2 (&file_actions, STDOUT_FILE_NO, STDERR_FILE_NO); + if (ret != 0) + goto error; + } + else if (errdes != STDERR_FILE_NO) + { + ret = posix_spawn_file_actions_adddup2 (&file_actions, errdes, STDERR_FILE_NO); + if (ret != 0) + goto error; + ret = posix_spawn_file_actions_addclose (&file_actions, errdes); + if (ret != 0) + goto error; + } + if (toclose >= 0) + { + ret = posix_spawn_file_actions_addclose (&file_actions, toclose); + if (ret != 0) + goto error; + } + if (env == NULL) + env = environ; + if ((flags & PEX_SEARCH) != 0) + ret = posix_spawnp (&pid, executable, &file_actions, NULL, argv, env); + else + ret = posix_spawn (&pid, executable, &file_actions, NULL, argv, env); + if (ret != 0) + goto error; + posix_spawn_file_actions_destroy(&file_actions); + + *errmsg = "close"; + if (in != STDIN_FILE_NO && close (in) < 0) + { + ret = errno; + goto error; + } + if (out != STDOUT_FILE_NO && close (out) < 0) + { + ret = errno; + goto error; + } + if (errdes != STDERR_FILE_NO && close (errdes) < 0) + { + ret = errno; + goto error; + } + + return pid; + + error: + *err = ret; + return (pid_t) -1; +} + +#elif defined(HAVE_SPAWNVE) && defined(HAVE_SPAWNVPE) /* Implementation of pex->exec_child using the Cygwin spawn operation. */ /* Subroutine of pex_unix_exec_child. Move OLD_FD to a new file descriptor -- 2.35.1