1 /* Test of posix_spawn() function with an inherited file descriptor 0.
2 Copyright (C) 2008-2021 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Bruno Haible <bruno@clisp.org>, 2020. */
19 /* Test whether passing a file descriptor open for reading, including the
20 current file position, works. */
31 #include <sys/types.h>
34 #define CHILD_PROGRAM_FILENAME "test-posix_spawn-inherit0"
35 #define DATA_FILENAME "test-posix_spawn-inh0-data.tmp"
41 char *argv[3] = { CHILD_PROGRAM_FILENAME, "-child", NULL };
47 /* Create a data file with specific contents. */
48 fp = fopen (DATA_FILENAME, "wb");
51 perror ("cannot create data file");
54 fwrite ("Halle Potta", 1, 11, fp);
55 if (fflush (fp) || fclose (fp))
57 perror ("cannot prepare data file");
61 /* Open the data file for reading. */
62 fp = freopen (DATA_FILENAME, "rb", stdin);
65 perror ("cannot open data file");
68 if (fflush (fp) || fseek (fp, 6, SEEK_SET)) /* needs gnulib module 'fflush' */
70 perror ("cannot seek in data file");
74 /* Test whether the child reads from fd 0 at the current file position. */
75 if ((err = posix_spawn (&child, CHILD_PROGRAM_FILENAME, NULL, NULL, argv, environ)) != 0)
78 perror ("subprocess failed");
82 while (waitpid (child, &status, 0) != child)
84 if (!WIFEXITED (status))
86 fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
89 exitstatus = WEXITSTATUS (status);
92 fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
98 perror ("cannot close data file");
102 /* Clean up data file. */
103 unlink (DATA_FILENAME);
111 /* Read from STDIN_FILENO. */
113 int nread = fread (buf, 1, sizeof (buf), stdin);
114 if (!(nread == 5 && memcmp (buf, "Potta", 5) == 0))
116 fprintf (stderr, "child: read %d bytes, expected %d bytes\n", nread, 5);
124 cleanup_then_die (int sig)
126 /* Clean up data file. */
127 unlink (DATA_FILENAME);
129 /* Re-raise the signal and die from it. */
130 signal (sig, SIG_DFL);
135 main (int argc, char *argv[])
139 if (!(argc > 1 && strcmp (argv[1], "-child") == 0))
141 /* This is the parent process. */
142 signal (SIGINT, cleanup_then_die);
143 signal (SIGTERM, cleanup_then_die);
145 signal (SIGHUP, cleanup_then_die);
148 exitstatus = parent_main ();
152 /* This is the child process. */
153 exitstatus = child_main ();