]> Savannah Git Hosting - gnulib.git/commitdiff
posix_spawn tests: Add two more tests.
authorBruno Haible <bruno@clisp.org>
Wed, 23 Dec 2020 22:26:42 +0000 (23:26 +0100)
committerBruno Haible <bruno@clisp.org>
Wed, 23 Dec 2020 22:26:42 +0000 (23:26 +0100)
* tests/test-posix_spawn-inherit0.c: New file, based on
tests/test-posix_spawn-open2.c.
* tests/test-posix_spawn-inherit1.c: New file, based on
tests/test-posix_spawn-open2.c.
* modules/posix_spawn-tests (Files): Add them.
(Depends-on): Add fflush.
(Makefile.am): Compile and run test-posix_spawn-inherit0 and
test-posix_spawn-inherit1.

ChangeLog
modules/posix_spawn-tests
tests/test-posix_spawn-inherit0.c [new file with mode: 0644]
tests/test-posix_spawn-inherit1.c [new file with mode: 0644]

index 23b83e0fd7df068eeaa1192474796fd52af86995..42e66bbd002d66eea44512fa5e2f5d8ba1c8ae98 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2020-12-23  Bruno Haible  <bruno@clisp.org>
+
+       posix_spawn tests: Add two more tests.
+       * tests/test-posix_spawn-inherit0.c: New file, based on
+       tests/test-posix_spawn-open2.c.
+       * tests/test-posix_spawn-inherit1.c: New file, based on
+       tests/test-posix_spawn-open2.c.
+       * modules/posix_spawn-tests (Files): Add them.
+       (Depends-on): Add fflush.
+       (Makefile.am): Compile and run test-posix_spawn-inherit0 and
+       test-posix_spawn-inherit1.
+
 2020-12-23  Bruno Haible  <bruno@clisp.org>
 
        posix_spawn tests: Add another test.
index f56ee6328efb88434a0a72e401b69b9dc65f3ba7..2c8b4a519a518c687d2648e0abcdd055421eb4b6 100644 (file)
@@ -1,6 +1,8 @@
 Files:
 tests/test-posix_spawn-open1.c
 tests/test-posix_spawn-open2.c
+tests/test-posix_spawn-inherit0.c
+tests/test-posix_spawn-inherit1.c
 tests/signature.h
 
 Depends-on:
@@ -11,6 +13,7 @@ stdbool
 unistd
 sys_wait
 environ
+fflush
 
 configure.ac:
 AC_EGREP_CPP([notposix], [[
@@ -26,8 +29,12 @@ Makefile.am:
 if POSIX_SPAWN_PORTED
 TESTS += \
   test-posix_spawn-open1 \
-  test-posix_spawn-open2
+  test-posix_spawn-open2 \
+  test-posix_spawn-inherit0 \
+  test-posix_spawn-inherit1
 check_PROGRAMS += \
   test-posix_spawn-open1 \
-  test-posix_spawn-open2
+  test-posix_spawn-open2 \
+  test-posix_spawn-inherit0 \
+  test-posix_spawn-inherit1
 endif
diff --git a/tests/test-posix_spawn-inherit0.c b/tests/test-posix_spawn-inherit0.c
new file mode 100644 (file)
index 0000000..027fd37
--- /dev/null
@@ -0,0 +1,156 @@
+/* Test of posix_spawn() function with an inherited file descriptor 0.
+   Copyright (C) 2008-2020 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 of the License, 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/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2020.  */
+
+/* Test whether passing a file descriptor open for reading, including the
+   current file position, works.  */
+
+#include <config.h>
+
+#include <spawn.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#define CHILD_PROGRAM_FILENAME "test-posix_spawn-inherit0"
+#define DATA_FILENAME "test-posix_spawn-inh0-data.tmp"
+
+static int
+parent_main (void)
+{
+  FILE *fp;
+  char *argv[3] = { CHILD_PROGRAM_FILENAME, "-child", NULL };
+  int err;
+  pid_t child;
+  int status;
+  int exitstatus;
+
+  /* Create a data file with specific contents.  */
+  fp = fopen (DATA_FILENAME, "wb");
+  if (fp == NULL)
+    {
+      perror ("cannot create data file");
+      return 1;
+    }
+  fwrite ("Halle Potta", 1, 11, fp);
+  if (fflush (fp) || fclose (fp))
+    {
+      perror ("cannot prepare data file");
+      return 1;
+    }
+
+  /* Open the data file for reading.  */
+  fp = freopen (DATA_FILENAME, "rb", stdin);
+  if (fp == NULL)
+    {
+      perror ("cannot open data file");
+      return 1;
+    }
+  if (fflush (fp) || fseek (fp, 6, SEEK_SET)) /* needs gnulib module 'fflush' */
+    {
+      perror ("cannot seek in data file");
+      return 1;
+    }
+
+  /* Test whether the child reads from fd 0 at the current file position.  */
+  if ((err = posix_spawn (&child, CHILD_PROGRAM_FILENAME, NULL, NULL, argv, environ)) != 0)
+    {
+      errno = err;
+      perror ("subprocess failed");
+      return 1;
+    }
+  status = 0;
+  while (waitpid (child, &status, 0) != child)
+    ;
+  if (!WIFEXITED (status))
+    {
+      fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
+      return 1;
+    }
+  exitstatus = WEXITSTATUS (status);
+  if (exitstatus != 0)
+    {
+      fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
+      return 1;
+    }
+
+  if (fclose (fp))
+    {
+      perror ("cannot close data file");
+      return 1;
+    }
+
+  /* Clean up data file.  */
+  unlink (DATA_FILENAME);
+
+  return 0;
+}
+
+static int
+child_main (void)
+{
+  /* Read from STDIN_FILENO.  */
+  char buf[1024];
+  int nread = fread (buf, 1, sizeof (buf), stdin);
+  if (!(nread == 5 && memcmp (buf, "Potta", 5) == 0))
+    {
+      fprintf (stderr, "child: read %d bytes, expected %d bytes\n", nread, 5);
+      return 1;
+    }
+
+  return 0;
+}
+
+static void
+cleanup_then_die (int sig)
+{
+  /* Clean up data file.  */
+  unlink (DATA_FILENAME);
+
+  /* Re-raise the signal and die from it.  */
+  signal (sig, SIG_DFL);
+  raise (sig);
+}
+
+int
+main (int argc, char *argv[])
+{
+  int exitstatus;
+
+  if (!(argc > 1 && strcmp (argv[1], "-child") == 0))
+    {
+      /* This is the parent process.  */
+      signal (SIGINT, cleanup_then_die);
+      signal (SIGTERM, cleanup_then_die);
+      #ifdef SIGHUP
+      signal (SIGHUP, cleanup_then_die);
+      #endif
+
+      exitstatus = parent_main ();
+    }
+  else
+    {
+      /* This is the child process.  */
+      exitstatus = child_main ();
+    }
+  return exitstatus;
+}
diff --git a/tests/test-posix_spawn-inherit1.c b/tests/test-posix_spawn-inherit1.c
new file mode 100644 (file)
index 0000000..f5e83d5
--- /dev/null
@@ -0,0 +1,159 @@
+/* Test of posix_spawn() function with an inherited file descriptor 1.
+   Copyright (C) 2008-2020 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 of the License, 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/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2020.  */
+
+/* Test whether passing a file descriptor open for writing, including the
+   current file position, works.  */
+
+#include <config.h>
+
+#include <spawn.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#define CHILD_PROGRAM_FILENAME "test-posix_spawn-inherit1"
+#define DATA_FILENAME "test-posix_spawn-inh1-data.tmp"
+
+static int
+parent_main (void)
+{
+  FILE *fp;
+  char *argv[3] = { CHILD_PROGRAM_FILENAME, "-child", NULL };
+  int err;
+  pid_t child;
+  int status;
+  int exitstatus;
+
+  /* Create a data file with specific contents.  */
+  fp = freopen (DATA_FILENAME, "wb", stdout);
+  if (fp == NULL)
+    {
+      perror ("cannot create data file");
+      return 1;
+    }
+  fwrite ("Halle X", 1, 7, fp);
+  if (fflush (fp) || fseek (fp, 6, SEEK_SET))
+    {
+      perror ("cannot prepare data file");
+      return 1;
+    }
+
+  /* Test whether the child writes to fd 1 at the current file position.  */
+  if ((err = posix_spawn (&child, CHILD_PROGRAM_FILENAME, NULL, NULL, argv, environ)) != 0)
+    {
+      errno = err;
+      perror ("subprocess failed");
+      return 1;
+    }
+  status = 0;
+  while (waitpid (child, &status, 0) != child)
+    ;
+  if (!WIFEXITED (status))
+    {
+      fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
+      return 1;
+    }
+  exitstatus = WEXITSTATUS (status);
+  if (exitstatus != 0)
+    {
+      fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
+      return 1;
+    }
+
+  if (fclose (fp))
+    {
+      perror ("cannot close data file");
+      return 1;
+    }
+
+  /* Check the contents of the data file.  */
+  fp = fopen (DATA_FILENAME, "rb");
+  if (fp == NULL)
+    {
+      perror ("cannot open data file");
+      return 1;
+    }
+  char buf[1024];
+  int nread = fread (buf, 1, sizeof (buf), fp);
+  if (!(nread == 11 && memcmp (buf, "Halle Potta", 11) == 0))
+    {
+      fprintf (stderr, "data file wrong: has %d bytes, expected %d bytes\n", nread, 11);
+      return 1;
+    }
+  if (fclose (fp))
+    {
+      perror ("cannot close data file");
+      return 1;
+    }
+
+  /* Clean up data file.  */
+  unlink (DATA_FILENAME);
+
+  return 0;
+}
+
+static int
+child_main (void)
+{
+  /* Write to STDOUT_FILENO.  */
+  fwrite ("Potta", 1, 5, stdout);
+  /* No 'fflush (stdout);' is needed.  It is implicit when the child process
+     exits.  */
+
+  return 0;
+}
+
+static void
+cleanup_then_die (int sig)
+{
+  /* Clean up data file.  */
+  unlink (DATA_FILENAME);
+
+  /* Re-raise the signal and die from it.  */
+  signal (sig, SIG_DFL);
+  raise (sig);
+}
+
+int
+main (int argc, char *argv[])
+{
+  int exitstatus;
+
+  if (!(argc > 1 && strcmp (argv[1], "-child") == 0))
+    {
+      /* This is the parent process.  */
+      signal (SIGINT, cleanup_then_die);
+      signal (SIGTERM, cleanup_then_die);
+      #ifdef SIGHUP
+      signal (SIGHUP, cleanup_then_die);
+      #endif
+
+      exitstatus = parent_main ();
+    }
+  else
+    {
+      /* This is the child process.  */
+      exitstatus = child_main ();
+    }
+  return exitstatus;
+}