dup2-tests: test previous patch
authorEric Blake <ebb9@byu.net>
Tue, 21 Jul 2009 12:48:56 +0000 (06:48 -0600)
committerEric Blake <ebb9@byu.net>
Tue, 21 Jul 2009 13:08:10 +0000 (07:08 -0600)
* modules/dup2-tests: New file.
* tests/test-dup2.c: Likewise.
* tests/test-open.c (main): Avoid unspecified behavior.
* tests/test-pipe.c (child_main): Use dup2 semantics to simplify
test.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
modules/dup2-tests [new file with mode: 0644]
tests/test-dup2.c [new file with mode: 0644]
tests/test-open.c
tests/test-pipe.c

index d87cc8e..6a89b40 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2009-07-21  Eric Blake  <ebb9@byu.net>
 
+       dup2-tests: test previous patch
+       * modules/dup2-tests: New file.
+       * tests/test-dup2.c: Likewise.
+       * tests/test-open.c (main): Avoid unspecified behavior.
+       * tests/test-pipe.c (child_main): Use dup2 semantics to simplify
+       test.
+
        dup2: work around mingw and cygwin 1.5 bug
        * m4/dup2.m4 (gl_FUNC_DUP2): Detect mingw bug.
        * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Add witness.
diff --git a/modules/dup2-tests b/modules/dup2-tests
new file mode 100644 (file)
index 0000000..9b1e7db
--- /dev/null
@@ -0,0 +1,12 @@
+Files:
+tests/test-dup2.c
+
+Depends-on:
+close
+open
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-dup2
+check_PROGRAMS += test-dup2
diff --git a/tests/test-dup2.c b/tests/test-dup2.c
new file mode 100644 (file)
index 0000000..67f49ef
--- /dev/null
@@ -0,0 +1,117 @@
+/* Test duplicating file descriptors.
+   Copyright (C) 2009 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 <http://www.gnu.org/licenses/>.  */
+
+/* Written by Eric Blake <ebb9@byu.net>, 2009.  */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Get declarations of the Win32 API functions.  */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#define ASSERT(expr) \
+  do                                                                        \
+    {                                                                       \
+      if (!(expr))                                                          \
+        {                                                                   \
+          fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
+          fflush (stderr);                                                  \
+          abort ();                                                         \
+        }                                                                   \
+    }                                                                       \
+  while (0)
+
+/* Return non-zero if FD is open.  */
+static int
+is_open (int fd)
+{
+#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, and there is no fcntl.  */
+  return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
+#else
+# ifndef F_GETFL
+#  error Please port fcntl to your platform
+# endif
+  return 0 <= fcntl (fd, F_GETFL);
+#endif
+}
+
+int
+main ()
+{
+  const char *file = "test-dup2.tmp";
+  char buffer[1];
+  int fd = open (file, O_CREAT | O_RDWR, 0600);
+
+  ASSERT (0 <= fd);
+  ASSERT (is_open (fd));
+  ASSERT (!is_open (fd + 1));
+  ASSERT (!is_open (fd + 2));
+
+  /* Assigning to self must be a no-op.  */
+  ASSERT (dup2 (fd, fd) == fd);
+  ASSERT (is_open (fd));
+
+  /* If the source is not open, then the destination is unaffected.  */
+  errno = 0;
+  ASSERT (dup2 (fd + 1, fd + 1) == -1);
+  ASSERT (errno == EBADF);
+  ASSERT (!is_open (fd + 1));
+  errno = 0;
+  ASSERT (dup2 (fd + 1, fd) == -1);
+  ASSERT (errno == EBADF);
+  ASSERT (is_open (fd));
+
+  /* The destination must be valid.  */
+  errno = 0;
+  ASSERT (dup2 (fd, -2) == -1);
+  ASSERT (errno == EBADF);
+
+  /* Using dup2 can skip fds.  */
+  ASSERT (dup2 (fd, fd + 2) == fd + 2);
+  ASSERT (is_open (fd));
+  ASSERT (!is_open (fd + 1));
+  ASSERT (is_open (fd + 2));
+
+  /* Prove that dup2 closes the previous occupant of a fd.  */
+  ASSERT (open ("/dev/null", O_WRONLY, 0600) == fd + 1);
+  ASSERT (dup2 (fd + 1, fd) == fd);
+  ASSERT (close (fd + 1) == 0);
+  ASSERT (write (fd, "1", 1) == 1);
+  ASSERT (dup2 (fd + 2, fd) == fd);
+  ASSERT (write (fd + 2, "2", 1) == 1);
+  ASSERT (lseek (fd, SEEK_SET, 0) == 0);
+  ASSERT (read (fd, buffer, 1) == 1);
+  ASSERT (*buffer == '2');
+
+  /* Clean up.  */
+  ASSERT (close (fd + 2) == 0);
+  ASSERT (close (fd) == 0);
+  ASSERT (unlink (file) == 0);
+
+  return 0;
+}
index 0eb8a33..f7bb543 100644 (file)
@@ -1,5 +1,5 @@
 /* Test of opening a file descriptor.
-   Copyright (C) 2007-2008 Free Software Foundation, Inc.
+   Copyright (C) 2007-2009 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
@@ -38,7 +38,7 @@
 int
 main ()
 {
-  ASSERT (open ("nonexist.ent/", O_CREAT, 0600) < 0);
+  ASSERT (open ("nonexist.ent/", O_CREAT | O_RDONLY, 0600) < 0);
   ASSERT (open ("/dev/null/", O_RDONLY) < 0);
 
   ASSERT (open ("/dev/null", O_RDONLY) >= 0);
index 16c72f6..404534d 100644 (file)
 #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, we arrange to have fd 10
@@ -59,6 +53,7 @@ child_main (int argc, char *argv[])
 {
   char buffer[2] = { 's', 't' };
   int fd;
+  int ret;
 
   ASSERT (argc == 3);
 
@@ -71,46 +66,22 @@ child_main (int argc, char *argv[])
   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++)
     {