1 /* Test of create_pipe_bidi/wait_subprocess.
2 Copyright (C) 2009 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, or (at your option)
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, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
21 #include "wait-process.h"
30 /* Depending on arguments, this test intentionally closes stderr or
31 starts life with stderr closed. So, the error messages might not
32 always print, but at least the exit status will be reliable. */
33 #define ASSERT(expr) \
38 fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
45 /* Code executed by the child process. argv[1] = "child". */
47 child_main (int argc, char *argv[])
55 /* Read one byte from fd 0, and write its value plus one to fd 1.
56 fd 2 should be closed iff the argument is 1. Check that no other file
57 descriptors leaked. */
59 ASSERT (read (STDIN_FILENO, buffer, 1) == 1);
62 ASSERT (write (STDOUT_FILENO, buffer, 1) == 1);
66 /* Try to keep stderr open for better diagnostics. */
67 i = fcntl (STDERR_FILENO, F_GETFL);
69 /* But allow compilation on mingw. You might need to disable this code for
70 debugging failures. */
71 i = close (STDERR_FILENO);
73 switch (atoi (argv[2]))
76 /* Expect fd 2 was open. */
80 /* Expect fd 2 was closed. */
82 ASSERT (errno == EBADF);
88 for (fd = 3; fd < 7; fd++)
91 ASSERT (close (fd) == -1);
92 ASSERT (errno == EBADF);
98 /* Create a bi-directional pipe to a test child, and validate that the
99 child program returns the expected output. The child is the same
100 program as the parent ARGV0, but with different arguments.
101 STDERR_CLOSED is true if we have already closed fd 2. */
103 test_pipe (const char *argv0, bool stderr_closed)
108 char buffer[2] = { 'a', 't' };
111 argv[0] = (char *) argv0;
112 argv[1] = (char *) "child";
113 argv[2] = (char *) (stderr_closed ? "1" : "0");
115 pid = create_pipe_bidi (argv0, argv0, argv, false, true, true, fd);
117 ASSERT (STDERR_FILENO < fd[0]);
118 ASSERT (STDERR_FILENO < fd[1]);
120 /* Push child's input. */
121 ASSERT (write (fd[1], buffer, 1) == 1);
123 /* Get child's output. */
124 ASSERT (read (fd[0], buffer, 2) == 1);
126 /* Wait for child. */
127 ASSERT (wait_subprocess (pid, argv0, true, false, true, true, NULL) == 0);
128 ASSERT (close (fd[0]) == 0);
129 ASSERT (close (fd[1]) == 0);
131 /* Check the result. */
132 ASSERT (buffer[0] == 'b');
133 ASSERT (buffer[1] == 't');
136 /* Code executed by the parent process. */
138 parent_main (int argc, char *argv[])
145 /* Selectively close various standard fds, to verify the child process is
146 not impacted by this. */
147 test = atoi (argv[1]);
182 /* Plug any file descriptor leaks inherited from outside world before
183 starting, so that child has a clean slate (at least for the fds that we
184 might be manipulating). */
185 for (fd = 3; fd < 7; fd++)
188 test_pipe (argv[0], test >= 4);
194 main (int argc, char *argv[])
197 if (strcmp (argv[1], "child") == 0)
198 return child_main (argc, argv);
200 return parent_main (argc, argv);