bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

fchdir fixes


From: Eric Blake
Subject: fchdir fixes
Date: Tue, 08 Dec 2009 06:42:37 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.23) Gecko/20090812 Thunderbird/2.0.0.23 Mnenhy/0.7.6.666

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

fchdir is working on mingw, which is about the only modern portability
target that lacks fchdir, but it is sure easier to test on other platforms
than mingw.  So before making rpl_fcntl (and having it call
_gl_register_dup at the right places), I decided to try './configure
ac_cv_func_fchdir=no' on a system with fchdir.  That failed miserably, so
I'm pushing the following.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkseV8wACgkQ84KuGfSFAYD+BACcD6InQ581gnb6Amfly/vfZKwp
gsEAnRCqvH3KINSelKDmGK0Deo5dCTBq
=Qs3n
-----END PGP SIGNATURE-----
>From 21a0a9e3ef07b457b04d483f8dd216bbdf06e860 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Mon, 7 Dec 2009 21:08:17 -0700
Subject: [PATCH 1/2] 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 <address@hidden>
---
 ChangeLog  |    9 +++++++++
 lib/dup2.c |   30 ++++++++++++++++--------------
 m4/dup2.m4 |    8 ++++----
 3 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7b78dca..40d2dac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-12-08  Eric Blake  <address@hidden>
+
+       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  <address@hidden>

        unlink: fix m4 detection
diff --git a/lib/dup2.c b/lib/dup2.c
index 140af1b..7ce49a2 100644
--- a/lib/dup2.c
+++ b/lib/dup2.c
@@ -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 */
diff --git a/m4/dup2.m4 b/m4/dup2.m4
index a74e915..26a6f60 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])
 ])
-- 
1.6.5.rc1


>From 2966d0d21fdc455b705e1b477dfe7e1b37f5f8e9 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Tue, 8 Dec 2009 06:13:05 -0700
Subject: [PATCH 2/2] fchdir: fix logic bugs

Configuring with ac_cv_func_fchdir=no on a system that has fchdir
and where open handles directories, just to test out the replacement
capabilities, uncovered an m4 test bug and a link failure on rpl_fstat.

* m4/fchdir.m4 (gl_FUNC_FCHDIR): Fix logic bug.
* tests/test-fchdir.c (main): Enhance test.
* lib/fchdir.c (rpl_fstat): Always provide if fchdir replacement
is in use.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog           |    6 ++++++
 lib/fchdir.c        |    7 +++----
 m4/fchdir.m4        |    4 ++--
 tests/test-fchdir.c |    8 +++++++-
 4 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 40d2dac..24d7e20 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2009-12-08  Eric Blake  <address@hidden>

+       fchdir: fix logic bugs
+       * m4/fchdir.m4 (gl_FUNC_FCHDIR): Fix logic bug.
+       * tests/test-fchdir.c (main): Enhance test.
+       * lib/fchdir.c (rpl_fstat): Always provide if fchdir replacement
+       is in use.
+
        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.
diff --git a/lib/fchdir.c b/lib/fchdir.c
index 16b17b4..4cc0f33 100644
--- a/lib/fchdir.c
+++ b/lib/fchdir.c
@@ -216,16 +216,15 @@ _gl_directory_name (int fd)
 /* Return stat information about FD in STATBUF.  Needed when
    rpl_open() used a dummy file to work around an open() that can't
    normally visit directories.  */
-#if REPLACE_OPEN_DIRECTORY
-# undef fstat
+#undef fstat
 int
 rpl_fstat (int fd, struct stat *statbuf)
 {
-  if (0 <= fd && fd < dirs_allocated && dirs[fd].name != NULL)
+  if (REPLACE_OPEN_DIRECTORY
+      && 0 <= fd && fd < dirs_allocated && dirs[fd].name != NULL)
     return stat (dirs[fd].name, statbuf);
   return fstat (fd, statbuf);
 }
-#endif

 /* Override opendir() and closedir(), to keep track of the open file
    descriptors.  Needed because there is a function dirfd().  */
diff --git a/m4/fchdir.m4 b/m4/fchdir.m4
index f0e4dc0..6243cc2 100644
--- a/m4/fchdir.m4
+++ b/m4/fchdir.m4
@@ -1,4 +1,4 @@
-# fchdir.m4 serial 10
+# fchdir.m4 serial 11
 dnl Copyright (C) 2006-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,
@@ -31,7 +31,7 @@ AC_DEFUN([gl_FUNC_FCHDIR],
     AC_CACHE_CHECK([whether open can visit directories],
       [gl_cv_func_open_directory_works],
       [AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <fcntl.h>
-]], [return open(".", O_RDONLY);])],
+]], [return open(".", O_RDONLY) < 0;])],
         [gl_cv_func_open_directory_works=yes],
         [gl_cv_func_open_directory_works=no],
         [gl_cv_func_open_directory_works="guessing no"])])
diff --git a/tests/test-fchdir.c b/tests/test-fchdir.c
index 53d6631..0419f43 100644
--- a/tests/test-fchdir.c
+++ b/tests/test-fchdir.c
@@ -26,6 +26,8 @@
 #include <stdlib.h>
 #include <string.h>

+#include "cloexec.h"
+
 #define ASSERT(expr) \
   do                                                                        \
     {                                                                       \
@@ -82,7 +84,11 @@ main (void)
          int new_fd = dup (fd);
          ASSERT (0 <= new_fd);
          ASSERT (close (fd) == 0);
-         fd = new_fd;
+         ASSERT (dup2 (new_fd, fd) == fd);
+         ASSERT (close (new_fd) == 0);
+         ASSERT (dup_cloexec (fd) == new_fd);
+         ASSERT (dup2 (new_fd, fd) == fd);
+         ASSERT (close (new_fd) == 0);
        }
     }

-- 
1.6.5.rc1


reply via email to

[Prev in Thread] Current Thread [Next in Thread]