diff --git a/gcc/libiberty/aclocal.m4 b/gcc/libiberty/aclocal.m4 index 3378316dce..ec3d692c6d 100644 --- a/gcc/libiberty/aclocal.m4 +++ b/gcc/libiberty/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- +# generated automatically by aclocal 1.16.5 -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2021 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/gcc/libiberty/config.in b/gcc/libiberty/config.in index f7052b5d95..050f6cd196 100644 --- a/gcc/libiberty/config.in +++ b/gcc/libiberty/config.in @@ -198,6 +198,12 @@ /* 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 `posix_spawnp' function. */ +#undef HAVE_POSIX_SPAWNP + /* Define to 1 if you have the header file. */ #undef HAVE_PROCESS_H @@ -249,6 +255,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/gcc/libiberty/configure b/gcc/libiberty/configure index 860f981fa1..24ea8f0916 100755 --- a/gcc/libiberty/configure +++ b/gcc/libiberty/configure @@ -5517,7 +5517,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" @@ -6026,7 +6026,8 @@ 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 \ + getsysinfo gettimeofday on_exit pipe2 posix_spawn posix_spawnp psignal \ + pstat_getdynamic pstat_getstatic \ realpath setrlimit spawnve spawnvpe strerror strsignal sysconf sysctl \ sysmp table times wait3 wait4" @@ -6049,7 +6050,8 @@ 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 posix_spawnp 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/gcc/libiberty/configure.ac b/gcc/libiberty/configure.ac index 28d996f9cf..98b63d55b6 100644 --- a/gcc/libiberty/configure.ac +++ b/gcc/libiberty/configure.ac @@ -277,7 +277,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 @@ -400,7 +400,8 @@ 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 \ + getsysinfo gettimeofday on_exit pipe2 posix_spawn posix_spawnp psignal \ + pstat_getdynamic pstat_getstatic \ realpath setrlimit spawnve spawnvpe strerror strsignal sysconf sysctl \ sysmp table times wait3 wait4" @@ -423,7 +424,8 @@ 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 posix_spawnp 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/gcc/libiberty/pex-unix.c b/gcc/libiberty/pex-unix.c index 33b5bce31c..ee52789d26 100644 --- a/gcc/libiberty/pex-unix.c +++ b/gcc/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" @@ -559,6 +562,171 @@ pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, return (pid_t) -1; } +#elif defined(HAVE_POSIX_SPAWN) && defined(HAVE_POSIX_SPAWNP) +/* Implementation of pex->exec_child using posix_spawn. */ + +static pid_t +pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, + int flags, const char *executable, + char * const * argv, char * const * env, + int in, int out, int errdes, + int toclose, const char **errmsg, int *err) +{ + int ret; + pid_t pid = -1; + posix_spawnattr_t attr; + posix_spawn_file_actions_t actions; + int attr_initialized = 0, actions_initialized = 0; + + *err = 0; + + ret = posix_spawnattr_init (&attr); + if (ret) + { + *err = ret; + *errmsg = "posix_spawnattr_init"; + goto exit; + } + attr_initialized = 1; + + /* Use vfork() on glibc <=2.24. */ +#ifdef POSIX_SPAWN_USEVFORK + ret = posix_spawnattr_setflags (&attr, POSIX_SPAWN_USEVFORK); + if (ret) + { + *err = ret; + *errmsg = "posix_spawnattr_setflags"; + goto exit; + } +#endif + + ret = posix_spawn_file_actions_init (&actions); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_init"; + goto exit; + } + actions_initialized = 1; + + if (in != STDIN_FILE_NO) + { + ret = posix_spawn_file_actions_adddup2 (&actions, in, STDIN_FILE_NO); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_adddup2"; + goto exit; + } + + ret = posix_spawn_file_actions_addclose (&actions, in); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_addclose"; + goto exit; + } + } + + if (out != STDOUT_FILE_NO) + { + ret = posix_spawn_file_actions_adddup2 (&actions, out, STDOUT_FILE_NO); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_adddup2"; + goto exit; + } + + ret = posix_spawn_file_actions_addclose (&actions, out); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_addclose"; + goto exit; + } + } + + if (errdes != STDERR_FILE_NO) + { + ret = posix_spawn_file_actions_adddup2 (&actions, errdes, STDERR_FILE_NO); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_adddup2"; + goto exit; + } + + ret = posix_spawn_file_actions_addclose (&actions, errdes); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_addclose"; + goto exit; + } + } + + if (toclose >= 0) + { + ret = posix_spawn_file_actions_addclose (&actions, toclose); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_addclose"; + goto exit; + } + } + + if ((flags & PEX_STDERR_TO_STDOUT) != 0) + { + ret = posix_spawn_file_actions_adddup2 (&actions, STDOUT_FILE_NO, STDERR_FILE_NO); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn_file_actions_adddup2"; + goto exit; + } + } + + if ((flags & PEX_SEARCH) != 0) + { + ret = posix_spawnp (&pid, executable, &actions, &attr, argv, env ? env : environ); + if (ret) + { + *err = ret; + *errmsg = "posix_spawnp"; + goto exit; + } + } + else + { + ret = posix_spawn (&pid, executable, &actions, &attr, argv, env ? env : environ); + if (ret) + { + *err = ret; + *errmsg = "posix_spawn"; + goto exit; + } + } + +exit: + if (actions_initialized) + posix_spawn_file_actions_destroy (&actions); + if (attr_initialized) + posix_spawnattr_destroy (&attr); + + if (!*err && in != STDIN_FILE_NO) + if (close (in)) + *errmsg = "close", *err = errno, pid = -1; + if (!*err && out != STDOUT_FILE_NO) + if (close (out)) + *errmsg = "close", *err = errno, pid = -1; + if (!*err && errdes != STDERR_FILE_NO) + if (close (errdes)) + *errmsg = "close", *err = errno, pid = -1; + + return pid; +} #else /* Implementation of pex->exec_child using standard vfork + exec. */