striconveh: Simplify last commit.
[gnulib.git] / tests / test-pipe.c
index 023f403..2dcab58 100644 (file)
@@ -1,5 +1,5 @@
 /* Test of create_pipe_bidi/wait_subprocess.
-   Copyright (C) 2009 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010 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
 #include "pipe.h"
 #include "wait-process.h"
 
-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-/* Get declarations of the Win32 API functions.  */
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-#endif
-
 #include <errno.h>
-#include <fcntl.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 /* Depending on arguments, this test intentionally closes stderr or
-   starts life with stderr closed.  So, the error messages might not
-   always print, but at least the exit status will be reliable.  */
-#define ASSERT(expr) \
-  do                                                                         \
-    {                                                                        \
-      if (!(expr))                                                           \
-        {                                                                    \
-          fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
-          fflush (stderr);                                                   \
-          abort ();                                                          \
-        }                                                                    \
-    }                                                                        \
-  while (0)
+   starts life with stderr closed.  So, we arrange to have fd 10
+   (outside the range of interesting fd's during the test) set up to
+   duplicate the original stderr.  */
+
+#define BACKUP_STDERR_FILENO 10
+#define ASSERT_STREAM myerr
+#include "macros.h"
+
+static FILE *myerr;
 
 /* Code executed by the child process.  argv[1] = "child".  */
 static int
 child_main (int argc, char *argv[])
 {
-  char buffer[1];
+  char buffer[2] = { 's', 't' };
   int fd;
+  int ret;
 
   ASSERT (argc == 3);
 
@@ -61,51 +52,27 @@ child_main (int argc, char *argv[])
      fd 2 should be closed iff the argument is 1.  Check that no other file
      descriptors leaked.  */
 
-  ASSERT (read (STDIN_FILENO, buffer, 1) == 1);
+  ASSERT (read (STDIN_FILENO, buffer, 2) == 1);
 
   buffer[0]++;
   ASSERT (write (STDOUT_FILENO, buffer, 1) == 1);
 
-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
-  /* On Win32, the initial state of unassigned standard file descriptors is
-     that they are open but point to an INVALID_HANDLE_VALUE.  Thus
-     close (STDERR_FILENO) would always succeed.  */
+  errno = 0;
+  ret = dup2 (STDERR_FILENO, STDERR_FILENO);
   switch (atoi (argv[2]))
     {
     case 0:
-      /* Expect fd 2 is open to a valid handle.  */
-      ASSERT ((HANDLE) _get_osfhandle (STDERR_FILENO) != INVALID_HANDLE_VALUE);
+      /* Expect fd 2 is open.  */
+      ASSERT (ret == STDERR_FILENO);
       break;
     case 1:
-      /* Expect fd 2 is pointing to INVALID_HANDLE_VALUE.  */
-      ASSERT ((HANDLE) _get_osfhandle (STDERR_FILENO) == INVALID_HANDLE_VALUE);
+      /* Expect fd 2 is closed.  */
+      ASSERT (ret == -1);
+      ASSERT (errno == EBADF);
       break;
     default:
       ASSERT (false);
     }
-#elif defined F_GETFL
-  /* On Unix, the initial state of unassigned standard file descriptors is
-     that they are closed.  */
-  {
-    int ret;
-    errno = 0;
-    ret = fcntl (STDERR_FILENO, F_GETFL);
-    switch (atoi (argv[2]))
-      {
-      case 0:
-       /* Expect fd 2 is open.  */
-       ASSERT (ret >= 0);
-       break;
-      case 1:
-       /* Expect fd 2 is closed.  */
-       ASSERT (ret < 0);
-       ASSERT (errno == EBADF);
-       break;
-      default:
-       ASSERT (false);
-      }
-  }
-#endif
 
   for (fd = 3; fd < 7; fd++)
     {
@@ -141,6 +108,7 @@ test_pipe (const char *argv0, bool stderr_closed)
 
   /* Push child's input.  */
   ASSERT (write (fd[1], buffer, 1) == 1);
+  ASSERT (close (fd[1]) == 0);
 
   /* Get child's output.  */
   ASSERT (read (fd[0], buffer, 2) == 1);
@@ -148,7 +116,6 @@ test_pipe (const char *argv0, bool stderr_closed)
   /* Wait for child.  */
   ASSERT (wait_subprocess (pid, argv0, true, false, true, true, NULL) == 0);
   ASSERT (close (fd[0]) == 0);
-  ASSERT (close (fd[1]) == 0);
 
   /* Check the result.  */
   ASSERT (buffer[0] == 'b');
@@ -215,9 +182,23 @@ parent_main (int argc, char *argv[])
 int
 main (int argc, char *argv[])
 {
-  ASSERT (argc >= 2);
+  if (argc < 2)
+    {
+      fprintf (stderr, "%s: need arguments\n", argv[0]);
+      return 2;
+    }
   if (strcmp (argv[1], "child") == 0)
-    return child_main (argc, argv);
-  else
-    return parent_main (argc, argv);
+    {
+      /* fd 2 might be closed, but fd BACKUP_STDERR_FILENO is the original
+         stderr.  */
+      myerr = fdopen (BACKUP_STDERR_FILENO, "w");
+      if (!myerr)
+        return 2;
+      return child_main (argc, argv);
+    }
+  /* We might close fd 2 later, so save it in fd 10.  */
+  if (dup2 (STDERR_FILENO, BACKUP_STDERR_FILENO) != BACKUP_STDERR_FILENO
+      || (myerr = fdopen (BACKUP_STDERR_FILENO, "w")) == NULL)
+    return 2;
+  return parent_main (argc, argv);
 }