]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
posix_spawnp tests: Add test against previous bug.
authorBruno Haible <bruno@clisp.org>
Mon, 10 Nov 2025 09:28:28 +0000 (10:28 +0100)
committerBruno Haible <bruno@clisp.org>
Mon, 10 Nov 2025 09:37:54 +0000 (10:37 +0100)
* tests/test-posix_spawnp-vfork.c: New file, based on
tests/test-posix_spawnp-script.c.
* modules/posix_spawnp-tests (Files): Add it.
(Makefile.am): Arrange to compile and test test-posix_spawnp-vfork.

ChangeLog
modules/posix_spawnp-tests
tests/test-posix_spawnp-vfork.c [new file with mode: 0644]

index 3b1613fb0d98d29755eecbe91f1ac782e49d2909..04e61f85064032a81acc7de26559c145c50527a8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-11-10  Bruno Haible  <bruno@clisp.org>
+
+       posix_spawnp tests: Add test against previous bug.
+       * tests/test-posix_spawnp-vfork.c: New file, based on
+       tests/test-posix_spawnp-script.c.
+       * modules/posix_spawnp-tests (Files): Add it.
+       (Makefile.am): Arrange to compile and test test-posix_spawnp-vfork.
+
 2025-11-08  Paul Eggert  <eggert@cs.ucla.edu>
 
        gendocs: port better to texi2html 5.0
index 11a36b3b68c7d0a33eee2a595df6149d1cc1707a..39f591cb10b6f23aa5045e28ca52a940d188b843 100644 (file)
@@ -4,6 +4,7 @@ tests/test-posix_spawn-dup2-stdout.in.sh
 tests/test-posix_spawn-dup2-stdin.c
 tests/test-posix_spawn-dup2-stdin.in.sh
 tests/test-posix_spawnp-script.c
+tests/test-posix_spawnp-vfork.c
 tests/executable-script
 tests/executable-script.sh
 tests/executable-shell-script
@@ -35,11 +36,13 @@ Makefile.am:
 TESTS += \
   test-posix_spawn-dup2-stdout \
   test-posix_spawn-dup2-stdin \
-  test-posix_spawnp-script
+  test-posix_spawnp-script \
+  test-posix_spawnp-vfork
 check_PROGRAMS += \
   test-posix_spawn-dup2-stdout \
   test-posix_spawn-dup2-stdin \
-  test-posix_spawnp-script
+  test-posix_spawnp-script \
+  test-posix_spawnp-vfork
 
 BUILT_SOURCES += test-posix_spawn-dup2-stdout.sh
 test-posix_spawn-dup2-stdout.sh: test-posix_spawn-dup2-stdout.in.sh
diff --git a/tests/test-posix_spawnp-vfork.c b/tests/test-posix_spawnp-vfork.c
new file mode 100644 (file)
index 0000000..633f8e7
--- /dev/null
@@ -0,0 +1,106 @@
+/* Test of posix_spawnp() function.
+   Copyright (C) 2020-2025 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <spawn.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "macros.h"
+
+/* Check an invocation via vfork() with a large $PATH (ca. 4 KB).
+   When configured with gl_cv_func_posix_spawnp_secure_exec=no, this test used
+   to crash on Linux/SPARC, Linux/ppc64, Linux/ppc64le, and Solaris/SPARC.  */
+
+int
+main ()
+{
+#if defined _WIN32 && !defined __CYGWIN__
+  /* There is no 'false' program on this platform, but no vfork() either.  */
+  fprintf (stderr, "Skipping test: no vfork() on this platform.\n");
+  return 77;
+#else
+
+  /* Components of file names are limited to ca. 255 characters on most
+     platforms.  (Cf. NAME_MAX in <limits.h>.)
+     Here is one with 250 characters.  */
+# define OOO "oooooooooooooooooooooooooooooooooooooooooooooooooo" \
+             "oooooooooooooooooooooooooooooooooooooooooooooooooo" \
+             "oooooooooooooooooooooooooooooooooooooooooooooooooo" \
+             "oooooooooooooooooooooooooooooooooooooooooooooooooo" \
+             "oooooooooooooooooooooooooooooooooooooooooooooooooo"
+  /* File names are limited to ca. 1024 characters on many platforms,
+     to ca. 4096 characters only on Linux and Cygwin, and unlimited only
+     on GNU/Hurd.  (Cf. PATH_MAX in <limits.h>.)
+     We prepend several directory names below this 1024 limit.  */
+# define ADD "/usr/bin/p" OOO "/" OOO "/" OOO "/" OOO ":" \
+             "/usr/bin/q" OOO "/" OOO "/" OOO "/" OOO ":" \
+             "/usr/bin/r" OOO "/" OOO "/" OOO "/" OOO ":" \
+             "/usr/bin/s" OOO "/" OOO "/" OOO "/" OOO ":"
+  const char *old_path = getenv ("PATH");
+  char *new_path = (char *) malloc (strlen (ADD) + strlen (old_path) + 1);
+  ASSERT (new_path != NULL);
+  memcpy (new_path, ADD, strlen (ADD));
+  strcpy (new_path + strlen (ADD), old_path);
+  ASSERT (setenv ("PATH", new_path, 1) == 0);
+
+  posix_spawnattr_t attr;
+  ASSERT (posix_spawnattr_init (&attr) == 0);
+  ASSERT (posix_spawnattr_setflags (&attr, POSIX_SPAWN_USEVFORK) == 0);
+
+  if (test_exit_status != EXIT_SUCCESS)
+    return test_exit_status;
+
+  /* Can't use 'false' here, because its exit status is only guaranteed to be
+     non-zero, and is in fact 255 on Solaris.  */
+  const char *prog = "sh";
+  const char *prog_argv[4] = { prog, "-c", "exit 1", NULL };
+  pid_t child;
+  int err = posix_spawnp (&child, prog, NULL, &attr, (char **) prog_argv, environ);
+  if (err != 0)
+    {
+      errno = err;
+      perror ("posix_spawn");
+      return 1;
+    }
+
+  /* Wait for child.  */
+  int status = 0;
+  while (waitpid (child, &status, 0) != child)
+    ;
+  if (!WIFEXITED (status))
+    {
+      fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
+      return 1;
+    }
+  int exitstatus = WEXITSTATUS (status);
+  if (exitstatus != 1)
+    {
+      fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
+      return 1;
+    }
+
+  return test_exit_status;
+
+#endif
+}