/* Specification. */
#include <stdio.h>
-/* Helpers. */
-#include <stdlib.h>
-#include <string.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#if GNULIB_POPEN_SAFER
-# include "stdio--.h"
-#endif
-
-#define ASSERT(expr) \
- do \
- { \
- if (!(expr)) \
- { \
- fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
- fflush (stderr); \
- abort (); \
- } \
- } \
- while (0)
-
-int
-main (int argc, char **argv)
-{
- size_t len;
- char *cmd;
- int i;
-
- /* Children - use the pipe. */
- if (argc > 1)
- {
- if (*argv[1] == 'r') /* Parent is reading, so we write. */
- ASSERT (putchar ('c') == 'c');
- else /* Parent is writing, so we read. */
- ASSERT (getchar () == 'p');
- /* Test that parent can read non-zero status. */
- return 42;
- }
-
- /* Parent - create read and write child, once under normal
- circumstances and once with stdin and stdout closed. */
- len = strlen (argv[0]);
- cmd = malloc (len + 3); /* Adding " r" and NUL. */
- ASSERT (cmd);
- /* We count on argv[0] not containing any shell metacharacters. */
- strcpy (cmd, argv[0]);
- cmd[len] = ' ';
- cmd[len + 2] = '\0';
- for (i = 0; i < 2; i++)
- {
- FILE *child;
- int status;
-
- if (i)
- {
- ASSERT (fclose (stdin) == 0);
- ASSERT (fclose (stdout) == 0);
- }
-
- cmd[len + 1] = 'r';
- ASSERT (child = popen (cmd, "r"));
- ASSERT (fgetc (child) == 'c');
- status = pclose (child);
- ASSERT (WIFEXITED (status));
- ASSERT (WEXITSTATUS (status) == 42);
- if (i)
- {
- ASSERT (dup2 (STDIN_FILENO, STDIN_FILENO) == -1);
- ASSERT (dup2 (STDOUT_FILENO, STDOUT_FILENO) == -1);
- }
-
- cmd[len + 1] = 'w';
- ASSERT (child = popen (cmd, "w"));
- ASSERT (fputc ('p', child) == 'p');
- status = pclose (child);
- ASSERT (WIFEXITED (status));
- ASSERT (WEXITSTATUS (status) == 42);
- if (i)
- {
- ASSERT (dup2 (STDIN_FILENO, STDIN_FILENO) == -1);
- ASSERT (dup2 (STDOUT_FILENO, STDOUT_FILENO) == -1);
- }
- }
- free (cmd);
- return 0;
-}
+#include "test-popen.h"