[PATCH] libiberty: Use posix_spawn in pex-unix when available.

2023-09-29 Thread Brendan Shanks
Hi,

This patch implements pex_unix_exec_child using posix_spawn when
available.

This should especially benefit recent macOS (where vfork just calls
fork), but should have equivalent or faster performance on all
platforms.
In addition, the implementation is substantially simpler than the
vfork+exec code path.

Tested on x86_64-linux.

libiberty/
* configure.ac (AC_CHECK_HEADERS): Add spawn.h.
(checkfuncs): Add posix_spawn, posix_spawnp.
(AC_CHECK_FUNCS): Add posix_spawn, posix_spawnp.
* configure, config.in: Rebuild.
* pex-unix.c [HAVE_POSIX_SPAWN] (pex_unix_exec_child): New function.

Signed-off-by: Brendan Shanks 
---
 libiberty/configure.ac |  8 +++--
 libiberty/pex-unix.c   | 72 ++
 2 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/libiberty/configure.ac b/libiberty/configure.ac
index 0748c592704..2488b031bc8 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,7 +412,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"
 
@@ -435,7 +436,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/libiberty/pex-unix.c b/libiberty/pex-unix.c
index 33b5bce31c2..d299852b7de 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"
@@ -559,6 +562,75 @@ 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)
+{
+  pid_t pid = -1;
+  posix_spawnattr_t attr;
+  posix_spawn_file_actions_t actions;
+  int attr_initialized = 0, actions_initialized = 0;
+
+  #define ERR_ON_FAILURE(ret, func) \
+do { if (ret) { *err = ret; *errmsg = func; goto exit; } else {} } while 
(0)
+
+  ERR_ON_FAILURE (posix_spawnattr_init (&attr), "posix_spawnattr_init");
+  attr_initialized = 1;
+
+  /* Use vfork() on glibc <=2.24. */
+#ifdef POSIX_SPAWN_USEVFORK
+  ERR_ON_FAILURE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_USEVFORK), 
"posix_spawnattr_setflags");
+#endif
+
+  ERR_ON_FAILURE (posix_spawn_file_actions_init (&actions), 
"posix_spawn_file_actions_init");
+  actions_initialized = 1;
+
+  if (in != STDIN_FILE_NO)
+{
+  ERR_ON_FAILURE (posix_spawn_file_actions_adddup2 (&actions, in, 
STDIN_FILE_NO), "posix_spawn_file_actions_adddup2");
+  ERR_ON_FAILURE (posix_spawn_file_actions_addclose (&actions, in), 
"posix_spawn_file_actions_addclose");
+}
+  if (out != STDOUT_FILE_NO)
+{
+  ERR_ON_FAILURE (posix_spawn_file_actions_adddup2 (&actions, out, 
STDOUT_FILE_NO), "posix_spawn_file_actions_addd

[PATCH v2] libiberty: Use posix_spawn in pex-unix when available.

2023-10-03 Thread Brendan Shanks
Hi,

This patch implements pex_unix_exec_child using posix_spawn when
available.

This should especially benefit recent macOS (where vfork just calls
fork), but should have equivalent or faster performance on all
platforms.
In addition, the implementation is substantially simpler than the
vfork+exec code path.

Tested on x86_64-linux.

v2: Fix error handling (previously the function would be run twice in
case of error), and don't use a macro that changes control flow.

libiberty/
* configure.ac (AC_CHECK_HEADERS): Add spawn.h.
(checkfuncs): Add posix_spawn, posix_spawnp.
(AC_CHECK_FUNCS): Add posix_spawn, posix_spawnp.
* configure, config.in: Rebuild.
* pex-unix.c [HAVE_POSIX_SPAWN] (pex_unix_exec_child): New function.

Signed-off-by: Brendan Shanks 
---
 libiberty/configure.ac |  8 ++--
 libiberty/pex-unix.c   | 93 ++
 2 files changed, 98 insertions(+), 3 deletions(-)

diff --git a/libiberty/configure.ac b/libiberty/configure.ac
index 0748c592704..2488b031bc8 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,7 +412,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"
 
@@ -435,7 +436,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/libiberty/pex-unix.c b/libiberty/pex-unix.c
index 33b5bce31c2..5e5ac529ad2 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"
@@ -559,6 +562,96 @@ 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;
+
+  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

[PATCH v3] libiberty: Use posix_spawn in pex-unix when available.

2023-10-04 Thread Brendan Shanks
Hi,

This patch implements pex_unix_exec_child using posix_spawn when
available.

This should especially benefit recent macOS (where vfork just calls
fork), but should have equivalent or faster performance on all
platforms.
In addition, the implementation is substantially simpler than the
vfork+exec code path.

Tested on x86_64-linux.

v2: Fix error handling (previously the function would be run twice in
case of error), and don't use a macro that changes control flow.

v3: Match file style for error-handling blocks, don't close
in/out/errdes on error, and check close() for errors.

libiberty/
* configure.ac (AC_CHECK_HEADERS): Add spawn.h.
(checkfuncs): Add posix_spawn, posix_spawnp.
(AC_CHECK_FUNCS): Add posix_spawn, posix_spawnp.
* configure, config.in: Rebuild.
* pex-unix.c [HAVE_POSIX_SPAWN] (pex_unix_exec_child): New function.

Signed-off-by: Brendan Shanks 
---
 libiberty/configure.ac |   8 +-
 libiberty/pex-unix.c   | 168 +
 2 files changed, 173 insertions(+), 3 deletions(-)

diff --git a/libiberty/configure.ac b/libiberty/configure.ac
index 0748c592704..2488b031bc8 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,7 +412,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"
 
@@ -435,7 +436,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/libiberty/pex-unix.c b/libiberty/pex-unix.c
index 33b5bce31c2..336799d1125 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"
@@ -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_FI

Ping: [PATCH v3] libiberty: Use posix_spawn in pex-unix when available.

2023-11-01 Thread Brendan Shanks
Polite ping on this.

> On Oct 4, 2023, at 11:28 AM, Brendan Shanks  wrote:
> 
> Hi,
> 
> This patch implements pex_unix_exec_child using posix_spawn when
> available.
> 
> This should especially benefit recent macOS (where vfork just calls
> fork), but should have equivalent or faster performance on all
> platforms.
> In addition, the implementation is substantially simpler than the
> vfork+exec code path.
> 
> Tested on x86_64-linux.
> 
> v2: Fix error handling (previously the function would be run twice in
> case of error), and don't use a macro that changes control flow.
> 
> v3: Match file style for error-handling blocks, don't close
> in/out/errdes on error, and check close() for errors.
> 
> libiberty/
> * configure.ac (AC_CHECK_HEADERS): Add spawn.h.
> (checkfuncs): Add posix_spawn, posix_spawnp.
> (AC_CHECK_FUNCS): Add posix_spawn, posix_spawnp.
> * configure, config.in: Rebuild.
> * pex-unix.c [HAVE_POSIX_SPAWN] (pex_unix_exec_child): New function.
> 
> Signed-off-by: Brendan Shanks 
> ---
> libiberty/configure.ac |   8 +-
> libiberty/pex-unix.c   | 168 +
> 2 files changed, 173 insertions(+), 3 deletions(-)
> 
> diff --git a/libiberty/configure.ac b/libiberty/configure.ac
> index 0748c592704..2488b031bc8 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,7 +412,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"
> 
> @@ -435,7 +436,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/libiberty/pex-unix.c b/libiberty/pex-unix.c
> index 33b5bce31c2..336799d1125 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"
> @@ -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 gli

[PATCH] testsuite: Fix bad-mapper-1.C test failures with posix_spawn

2023-11-11 Thread Brendan Shanks
bad-mapper-1.C has been failing since the posix_spawn codepath was added
to libiberty, adjust the check to accept the changed error message.

Patch has been verified on x86_64 Linux.

gcc/testsuite:

* g++.dg/modules/bad-mapper-1.C: Also accept posix_spawn.

Signed-off-by: Brendan Shanks 
---
 gcc/testsuite/g++.dg/modules/bad-mapper-1.C | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/modules/bad-mapper-1.C 
b/gcc/testsuite/g++.dg/modules/bad-mapper-1.C
index 4b2312885d8..53e3e1d0c88 100644
--- a/gcc/testsuite/g++.dg/modules/bad-mapper-1.C
+++ b/gcc/testsuite/g++.dg/modules/bad-mapper-1.C
@@ -1,6 +1,6 @@
 //  { dg-additional-options "-fmodules-ts -fmodule-mapper=|this-will-not-work" 
}
 import unique1.bob;
-// { dg-error "-:failed (exec|CreateProcess).*mapper.* .*this-will-not-work" 
"" { target { ! { *-*-darwin[89]* *-*-darwin10* } } } 0 }
+// { dg-error "-:failed (exec|CreateProcess|posix_spawn).*mapper.* 
.*this-will-not-work" "" { target { ! { *-*-darwin[89]* *-*-darwin10* } } } 0 }
 // { dg-prune-output "fatal error:" }
 // { dg-prune-output "failed to read" }
 // { dg-prune-output "compilation terminated" }
-- 
2.41.0