* lib/stat-time.h (USE_BIRTHTIME): Remove.
[gnulib.git] / lib / stat-time.h
index f72faf9..e98cee3 100644 (file)
@@ -1,6 +1,6 @@
 /* stat-related time functions.
 
-   Copyright (C) 2005 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007 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
@@ -21,7 +21,8 @@
 #ifndef STAT_TIME_H
 #define STAT_TIME_H 1
 
-#include "timespec.h"
+#include <sys/stat.h>
+#include <time.h>
 
 /* STAT_TIMESPEC (ST, ST_XTIM) is the ST_XTIM member for *ST of type
    struct timespec, if available.  If not, then STAT_TIMESPEC_NS (ST,
 
    These macros are private to stat-time.h.  */
 #if defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
-# define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim)
+# ifdef TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC
+#  define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim)
+# else
+#  define STAT_TIMESPEC_NS(st, st_xtim) ((st)->st_xtim.tv_nsec)
+# endif
 #elif defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
 # define STAT_TIMESPEC(st, st_xtim) ((st)->st_xtim##espec)
 #elif defined HAVE_STRUCT_STAT_ST_ATIMENSEC
@@ -48,8 +53,6 @@ get_stat_atime_ns (struct stat const *st)
   return STAT_TIMESPEC (st, st_atim).tv_nsec;
 # elif defined STAT_TIMESPEC_NS
   return STAT_TIMESPEC_NS (st, st_atim);
-# elif defined HAVE_STRUCT_STAT_ST_SPARE1
-  return st->st_spare1 * 1000;
 # else
   return 0;
 # endif
@@ -63,8 +66,6 @@ get_stat_ctime_ns (struct stat const *st)
   return STAT_TIMESPEC (st, st_ctim).tv_nsec;
 # elif defined STAT_TIMESPEC_NS
   return STAT_TIMESPEC_NS (st, st_ctim);
-# elif defined HAVE_STRUCT_STAT_ST_SPARE1
-  return st->st_spare3 * 1000;
 # else
   return 0;
 # endif
@@ -78,8 +79,19 @@ get_stat_mtime_ns (struct stat const *st)
   return STAT_TIMESPEC (st, st_mtim).tv_nsec;
 # elif defined STAT_TIMESPEC_NS
   return STAT_TIMESPEC_NS (st, st_mtim);
-# elif defined HAVE_STRUCT_STAT_ST_SPARE1
-  return st->st_spare2 * 1000;
+# else
+  return 0;
+# endif
+}
+
+/* Return the nanosecond component of *ST's birth time.  */
+static inline long int
+get_stat_birthtime_ns (struct stat const *st)
+{
+# if defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
+  return STAT_TIMESPEC (st, st_birthtim).tv_nsec;
+# elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC
+  return STAT_TIMESPEC_NS (st, st_birthtim);
 # else
   return 0;
 # endif
@@ -127,4 +139,41 @@ get_stat_mtime (struct stat const *st)
 #endif
 }
 
+/* Return *ST's birth time, if available; otherwise return a value
+   with negative tv_nsec.  */
+static inline struct timespec
+get_stat_birthtime (struct stat const *st)
+{
+  struct timespec t;
+
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
+  t = STAT_TIMESPEC (st, st_birthtim);
+#elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC
+  t.tv_sec = st->st_birthtime;
+  t.tv_nsec = st->st_birthtimensec;
+
+  /* NetBSD sometimes signals the absence of knowledge by using zero.
+     Attempt to work around this bug.  This sometimes reports failure
+     even for valid time stamps.  Also, sometimes NetBSD returns junk
+     in the birth time fields; work around this bug if it it is
+     detected.  There's no need to detect negative tv_nsec junk as
+     negative tv_nsec already indicates an error.  */
+  if (t.tv_sec == 0 || 1000000000 <= t.tv_nsec)
+    t.tv_nsec = -1;
+
+#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+  /* Woe32 native platforms (but not Cygwin) put the "file creation
+     time" in st_ctime (!).  See
+     <http://msdn2.microsoft.com/de-de/library/14h5k7ff(VS.80).aspx>.  */
+  t.tv_sec = st->st_ctime;
+  t.tv_nsec = 0;
+#else
+  /* Birth time is not supported.  Set tv_sec to avoid undefined behavior.  */
+  t.tv_sec = -1;
+  t.tv_nsec = -1;
+#endif
+
+  return t;
+}
+
 #endif