From 21a0a9e3ef07b457b04d483f8dd216bbdf06e860 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Mon, 7 Dec 2009 21:08:17 -0700 Subject: [PATCH] dup2: fix logic bugs 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 --- ChangeLog | 9 +++++++++ lib/dup2.c | 30 ++++++++++++++++-------------- m4/dup2.m4 | 8 ++++---- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b78dca31..40d2dacc8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-12-08 Eric Blake + + 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 unlink: fix m4 detection diff --git a/lib/dup2.c b/lib/dup2.c index 140af1b9f..7ce49a2b7 100644 --- a/lib/dup2.c +++ b/lib/dup2.c @@ -32,7 +32,7 @@ # include #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 */ diff --git a/m4/dup2.m4 b/m4/dup2.m4 index a74e915bb..26a6f60e3 100644 --- a/m4/dup2.m4 +++ b/m4/dup2.m4 @@ -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]) ]) -- 2.11.0