dup2: fix logic bugs
authorEric Blake <ebb9@byu.net>
Tue, 8 Dec 2009 04:08:17 +0000 (21:08 -0700)
committerEric Blake <ebb9@byu.net>
Tue, 8 Dec 2009 13:29:15 +0000 (06:29 -0700)
If the platform has dup2, don't register with fchdir if the
destination was -1.

If the platform lacks dup2 (are there any these days?), then don't
close the destination unless the source is valid, make sure errno
is correct, and only register with fchdir on fcntl (since dup is
already overridden to do a registration).

* lib/dup2.c (dup2): Fix logic bugs.  Use HAVE_DUP2 rather than
REPLACE_DUP2 to decide when rpl_dup2 is needed.
* m4/dup2.m4 (gl_REPLACE_DUP2): Only define REPLACE_DUP2 when dup2
exists.
(gl_FUNC_DUP2): Drop unneeded AC_SUBST.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
lib/dup2.c
m4/dup2.m4

index 7b78dca31fb4018b704ae9d9bcb61a302b27075d..40d2dacc8bc1909d7bd930225e27fb09e449ba4a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-12-08  Eric Blake  <ebb9@byu.net>
+
+       dup2: fix logic bugs
+       * lib/dup2.c (dup2): Fix logic bugs.  Use HAVE_DUP2 rather than
+       REPLACE_DUP2 to decide when rpl_dup2 is needed.
+       * m4/dup2.m4 (gl_REPLACE_DUP2): Only define REPLACE_DUP2 when dup2
+       exists.
+       (gl_FUNC_DUP2): Drop unneeded AC_SUBST.
+
 2009-12-07  Eric Blake  <ebb9@byu.net>
 
        unlink: fix m4 detection
index 140af1b9fb4d8e7d19404c74b827dd2a5acedd22..7ce49a2b7be44448dc910b9ced7a8957facf8522 100644 (file)
@@ -32,7 +32,7 @@
 # include <windows.h>
 #endif
 
-#if REPLACE_DUP2
+#if HAVE_DUP2
 
 # undef dup2
 
@@ -70,14 +70,14 @@ rpl_dup2 (int fd, int desired_fd)
   /* Correct a cygwin 1.5.x errno value.  */
   else if (result == -1 && errno == EMFILE)
     errno = EBADF;
-#if REPLACE_FCHDIR
-  if (fd != desired_fd && result == desired_fd)
-    result = _gl_register_dup (fd, desired_fd);
-#endif
+# if REPLACE_FCHDIR
+  if (fd != desired_fd && result != -1)
+    result = _gl_register_dup (fd, result);
+# endif
   return result;
 }
 
-#else /* !REPLACE_DUP2 */
+#else /* !HAVE_DUP2 */
 
 /* On older platforms, dup2 did not exist.  */
 
@@ -102,19 +102,21 @@ dupfd (int fd, int desired_fd)
 int
 dup2 (int fd, int desired_fd)
 {
-  int result;
-  if (fd == desired_fd)
-    return fcntl (fd, F_GETFL) < 0 ? -1 : fd;
+  int result = fcntl (fd, F_GETFL) < 0 ? -1 : fd;
+  if (result == -1 || fd == desired_fd)
+    return result;
   close (desired_fd);
 # ifdef F_DUPFD
   result = fcntl (fd, F_DUPFD, desired_fd);
+#  if REPLACE_FCHDIR
+  if (0 <= result)
+    result = _gl_register_dup (fd, result);
+#  endif
 # else
   result = dupfd (fd, desired_fd);
 # endif
-#if REPLACE_FCHDIR
-  if (0 <= result)
-    result = _gl_register_dup (fd, desired_fd);
-#endif
+  if (result == -1 && (errno == EMFILE || errno == EINVAL))
+    errno = EBADF;
   return result;
 }
-#endif /* !REPLACE_DUP2 */
+#endif /* !HAVE_DUP2 */
index a74e915bb477461ba2932113e6288360f4fb2d53..26a6f60e3430f9a37eee51e2e31d3d06204dfa8e 100644 (file)
@@ -1,4 +1,4 @@
-#serial 9
+#serial 10
 dnl Copyright (C) 2002, 2005, 2007, 2009 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -46,13 +46,13 @@ AC_DEFUN([gl_FUNC_DUP2],
       gl_REPLACE_DUP2
     fi
   fi
-  AC_DEFINE_UNQUOTED([REPLACE_DUP2], [$REPLACE_DUP2],
-    [Define to 1 if dup2 returns 0 instead of the target fd.])
 ])
 
 AC_DEFUN([gl_REPLACE_DUP2],
 [
   AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
-  REPLACE_DUP2=1
+  if test $ac_cv_func_dup2 = yes; then
+    REPLACE_DUP2=1
+  fi
   AC_LIBOBJ([dup2])
 ])