From: Bruno Haible Date: Wed, 23 Dec 2020 22:26:42 +0000 (+0100) Subject: posix_spawn tests: Add two more tests. X-Git-Tag: v1.0~3335 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=beaaf40c19e82190db4be934a80265685e66b38f;p=gnulib.git 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. --- diff --git a/ChangeLog b/ChangeLog index 23b83e0fd7..42e66bbd00 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2020-12-23 Bruno Haible + + 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 posix_spawn tests: Add another test. diff --git a/modules/posix_spawn-tests b/modules/posix_spawn-tests index f56ee6328e..2c8b4a519a 100644 --- a/modules/posix_spawn-tests +++ b/modules/posix_spawn-tests @@ -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 index 0000000000..027fd3765f --- /dev/null +++ b/tests/test-posix_spawn-inherit0.c @@ -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 . */ + +/* Written by Bruno Haible , 2020. */ + +/* Test whether passing a file descriptor open for reading, including the + current file position, works. */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#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 index 0000000000..f5e83d517f --- /dev/null +++ b/tests/test-posix_spawn-inherit1.c @@ -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 . */ + +/* Written by Bruno Haible , 2020. */ + +/* Test whether passing a file descriptor open for writing, including the + current file position, works. */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#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; +}