On 09/18/2011 09:59 PM, Paul Eggert wrote:
* lib/utimens.c (fdutimens): Don't invoke dup2; it's not needed
to work around the Linux kernel bug.
* modules/utimens (Depends-on): Remove dup2.
---
  ChangeLog       |    7 +++++++
  lib/utimens.c   |   13 ++++---------
  modules/utimens |    1 -
  3 files changed, 11 insertions(+), 10 deletions(-)

-  /* Require that at least one of FD or FILE are valid.  Works around
+  /* Require that at least one of FD or FILE are potentially valid, to avoid
       a Linux bug where futimens (AT_FDCWD, NULL) changes "." rather
       than failing.  */
-  if (!file)
+  if (fd<  0&&  !file)
      {
-      if (fd<  0)
-        {
-          errno = EBADF;
-          return -1;
-        }
-      if (dup2 (fd, fd) != fd)
-        return -1;
+      errno = EBADF;
+      return -1;
      }

I take it that the reason this still worked for a closed fd >= 0 is that the kernel properly returns EBADF later on when we attempt the futimens; and it was only negative fds where the kernel/glibc issue was leaking through. But I don't see that test currently in the gnulib test suite. So I'm pushing this additional followup, to fix that shortcoming in the testsuite.

diff --git i/ChangeLog w/ChangeLog
index ddbbe0e..32f3723 100644
--- i/ChangeLog
+++ w/ChangeLog
@@ -1,5 +1,9 @@
 2011-09-19  Eric Blake  <ebl...@redhat.com>

+       futimens: enhance test
+       * tests/test-futimens.h (test_futimens): Also check for EBADF on
+       closed non-negative fd.
+
        date: accept 'hence' as opposite of 'ago'
        * lib/parse-datetime.y (relative_time_table): Add 'hence'.
        * tests/test-parse-datetime.c (main): Enhance test.
diff --git i/tests/test-futimens.h w/tests/test-futimens.h
index 13e7d92..451edd9 100644
--- i/tests/test-futimens.h
+++ w/tests/test-futimens.h
@@ -81,6 +81,14 @@ test_futimens (int (*func) (int, struct timespec const *),
   ASSERT (func (-1, NULL) == -1);
   ASSERT (errno == EBADF);
   {
+    int fd = dup (0);
+    ASSERT (0 <= fd);
+    ASSERT (close (fd) == 0);
+    errno = 0;
+    ASSERT (func (fd, NULL) == -1);
+    ASSERT (errno == EBADF);
+  }
+  {
     struct timespec ts[2] = { { Y2K, UTIME_BOGUS_POS }, { Y2K, 0 } };
     errno = 0;
     ASSERT (func (fd, ts) == -1);

--
Eric Blake   ebl...@redhat.com    +1-801-349-2682
Libvirt virtualization library http://libvirt.org

Reply via email to