openat, utimens: whitespace cleanup
[pspp] / lib / utimens.c
index 25bc9653252d28a507494d01aab5494b33dd483a..86c1c5a222d560c908b27d4a34dc1fc86d2540f0 100644 (file)
@@ -1,7 +1,7 @@
 /* Set file access and modification times.
 
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software
-   Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 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
@@ -44,16 +44,6 @@ struct utimbuf
 };
 #endif
 
-/* Some systems don't have ENOSYS.  */
-#ifndef ENOSYS
-# ifdef ENOTSUP
-#  define ENOSYS ENOTSUP
-# else
-/* Some systems don't have ENOTSUP either.  */
-#  define ENOSYS EINVAL
-# endif
-#endif
-
 #ifndef __attribute__
 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
 #  define __attribute__(x)
@@ -76,7 +66,7 @@ struct utimbuf
 
 int
 gl_futimens (int fd ATTRIBUTE_UNUSED,
-            char const *file, struct timespec const timespec[2])
+             char const *file, struct timespec const timespec[2])
 {
   /* Some Linux-based NFS clients are buggy, and mishandle time stamps
      of files in NFS file systems in some cases.  We have no
@@ -96,100 +86,126 @@ gl_futimens (int fd ATTRIBUTE_UNUSED,
 #endif
 
   /* POSIX 200x added two interfaces to set file timestamps with
-     nanosecond resolution.  */
+     nanosecond resolution.  We provide a fallback for ENOSYS (for
+     example, compiling against Linux 2.6.25 kernel headers and glibc
+     2.7, but running on Linux 2.6.18 kernel).  */
 #if HAVE_UTIMENSAT
   if (fd < 0)
-    return utimensat (AT_FDCWD, file, timespec, 0);
+    {
+      int result = utimensat (AT_FDCWD, file, timespec, 0);
+# ifdef __linux__
+      /* Work around what might be a kernel bug:
+         http://bugzilla.redhat.com/442352
+         http://bugzilla.redhat.com/449910
+         It appears that utimensat can mistakenly return 280 rather
+         than -1 upon failure.
+         FIXME: remove in 2010 or whenever the offending kernels
+         are no longer in common use.  */
+      if (0 < result)
+        errno = ENOSYS;
+# endif
+
+      if (result == 0 || errno != ENOSYS)
+        return result;
+    }
 #endif
 #if HAVE_FUTIMENS
-  return futimens (fd, timespec);
-#else
+  {
+    int result = futimens (fd, timespec);
+# ifdef __linux__
+    /* Work around the same bug as above.  */
+    if (0 < result)
+      errno = ENOSYS;
+# endif
+    if (result == 0 || errno != ENOSYS)
+      return result;
+  }
+#endif
 
   /* The platform lacks an interface to set file timestamps with
      nanosecond resolution, so do the best we can, discarding any
      fractional part of the timestamp.  */
   {
-# if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES
+#if HAVE_FUTIMESAT || HAVE_WORKING_UTIMES
     struct timeval timeval[2];
     struct timeval const *t;
     if (timespec)
       {
-       timeval[0].tv_sec = timespec[0].tv_sec;
-       timeval[0].tv_usec = timespec[0].tv_nsec / 1000;
-       timeval[1].tv_sec = timespec[1].tv_sec;
-       timeval[1].tv_usec = timespec[1].tv_nsec / 1000;
-       t = timeval;
+        timeval[0].tv_sec = timespec[0].tv_sec;
+        timeval[0].tv_usec = timespec[0].tv_nsec / 1000;
+        timeval[1].tv_sec = timespec[1].tv_sec;
+        timeval[1].tv_usec = timespec[1].tv_nsec / 1000;
+        t = timeval;
       }
     else
       t = NULL;
 
     if (fd < 0)
       {
-#  if HAVE_FUTIMESAT
-       return futimesat (AT_FDCWD, file, t);
-#  endif
+# if HAVE_FUTIMESAT
+        return futimesat (AT_FDCWD, file, t);
+# endif
       }
     else
       {
-       /* If futimesat or futimes fails here, don't try to speed things
-          up by returning right away.  glibc can incorrectly fail with
-          errno == ENOENT if /proc isn't mounted.  Also, Mandrake 10.0
-          in high security mode doesn't allow ordinary users to read
-          /proc/self, so glibc incorrectly fails with errno == EACCES.
-          If errno == EIO, EPERM, or EROFS, it's probably safe to fail
-          right away, but these cases are rare enough that they're not
-          worth optimizing, and who knows what other messed-up systems
-          are out there?  So play it safe and fall back on the code
-          below.  */
-#  if HAVE_FUTIMESAT
-       if (futimesat (fd, NULL, t) == 0)
-         return 0;
-#  elif HAVE_FUTIMES
-       if (futimes (fd, t) == 0)
-         return 0;
-#  endif
+        /* If futimesat or futimes fails here, don't try to speed things
+           up by returning right away.  glibc can incorrectly fail with
+           errno == ENOENT if /proc isn't mounted.  Also, Mandrake 10.0
+           in high security mode doesn't allow ordinary users to read
+           /proc/self, so glibc incorrectly fails with errno == EACCES.
+           If errno == EIO, EPERM, or EROFS, it's probably safe to fail
+           right away, but these cases are rare enough that they're not
+           worth optimizing, and who knows what other messed-up systems
+           are out there?  So play it safe and fall back on the code
+           below.  */
+# if HAVE_FUTIMESAT
+        if (futimesat (fd, NULL, t) == 0)
+          return 0;
+# elif HAVE_FUTIMES
+        if (futimes (fd, t) == 0)
+          return 0;
+# endif
       }
-# endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */
+#endif /* HAVE_FUTIMESAT || HAVE_WORKING_UTIMES */
 
     if (!file)
       {
-# if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES))
-       errno = ENOSYS;
-# endif
+#if ! (HAVE_FUTIMESAT || (HAVE_WORKING_UTIMES && HAVE_FUTIMES))
+        errno = ENOSYS;
+#endif
 
-       /* Prefer EBADF to ENOSYS if both error numbers apply.  */
-       if (errno == ENOSYS)
-         {
-           int fd2 = dup (fd);
-           int dup_errno = errno;
-           if (0 <= fd2)
-             close (fd2);
-           errno = (fd2 < 0 && dup_errno == EBADF ? EBADF : ENOSYS);
-         }
-
-       return -1;
+        /* Prefer EBADF to ENOSYS if both error numbers apply.  */
+        if (errno == ENOSYS)
+          {
+            int fd2 = dup (fd);
+            int dup_errno = errno;
+            if (0 <= fd2)
+              close (fd2);
+            errno = (fd2 < 0 && dup_errno == EBADF ? EBADF : ENOSYS);
+          }
+
+        return -1;
       }
 
-# if HAVE_WORKING_UTIMES
+#if HAVE_WORKING_UTIMES
     return utimes (file, t);
-# else
+#else
     {
       struct utimbuf utimbuf;
       struct utimbuf const *ut;
       if (timespec)
-       {
-         utimbuf.actime = timespec[0].tv_sec;
-         utimbuf.modtime = timespec[1].tv_sec;
-         ut = &utimbuf;
-       }
+        {
+          utimbuf.actime = timespec[0].tv_sec;
+          utimbuf.modtime = timespec[1].tv_sec;
+          ut = &utimbuf;
+        }
       else
-       ut = NULL;
+        ut = NULL;
 
       return utime (file, ut);
     }
-# endif /* !HAVE_WORKING_UTIMES */
+#endif /* !HAVE_WORKING_UTIMES */
   }
-#endif /* !HAVE_FUTIMENS */
 }
 
 /* Set the access and modification time stamps of FILE to be