r13423: Write wrapper functions (and configure tests) so we can
authorJeremy Allison <jra@samba.org>
Fri, 10 Feb 2006 01:43:33 +0000 (01:43 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:10:01 +0000 (11:10 -0500)
always assume we can get a struct timespec out of a stat
struct. This will allow us to portably move to nsec timestamps
on files and directories in the file server code in future.
Jeremy.

source/configure.in
source/lib/time.c
source/smbd/notify_hash.c

index 6dedbd3441524ac7053b1bc62c8805370c4c4ae6..9774479acbf8729de941f04569ac6335527b0af9 100644 (file)
@@ -1395,6 +1395,45 @@ if test x"$samba_stat_hires" = x"yes" ; then
            [whether struct stat has sub-second timestamps])
 fi
 
+AC_CACHE_CHECK([whether struct stat has sub-second timestamps without struct timespec], samba_stat_hires_notimespec,
+    [
+       AC_TRY_COMPILE(
+           [
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+           ],
+           [
+               struct timespec t;
+               struct stat s = {0};
+               t.tv_sec = s.st_mtime;
+               t.tv_nsec = s.st_mtimensec;
+               t.tv_sec = s.st_ctime;
+               t.tv_nsec = s.st_ctimensec;
+               t.tv_sec = s.st_atime;
+               t.tv_nsec = s.st_atimensec;
+           ],
+           samba_stat_hires=yes, samba_stat_hires=no)
+    ])
+
+if test x"$samba_stat_hires_notimespec" = x"yes" ; then
+    AC_DEFINE(HAVE_STAT_ST_MTIMENSEC, 1, [whether struct stat contains st_mtimensec])
+    AC_DEFINE(HAVE_STAT_ST_ATIMENSEC, 1, [whether struct stat contains st_atimensec])
+    AC_DEFINE(HAVE_STAT_ST_CTIMENSEC, 1, [whether struct stat contains st_ctimensec])
+    AC_DEFINE(HAVE_STAT_HIRES_TIMESTAMPS, 1,
+           [whether struct stat has sub-second timestamps without struct timespec])
+fi
+
 #####################################
 # we might need the resolv library on some systems
 AC_CHECK_LIB(resolv, dn_expand)
index f87e53fef528345fb654c88de97f6d3fa801c16a..b6a22a30988d770d581a43fce836270f29d375d4 100644 (file)
@@ -955,3 +955,105 @@ time_t generalized_to_unix_time(const char *str)
 
        return timegm(&tm);
 }
+
+/****************************************************************************
+ Return all the possible time fields from a stat struct as a timespec.
+****************************************************************************/
+
+struct timespec get_atimespec(SMB_STRUCT_STAT *pst)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+       struct timespec ret;
+
+       /* Old system - no ns timestamp. */
+       ret.tv_sec = pst->st_atime;
+       ret.tv_nsec = 0;
+       return ret;
+#else
+#if defined(HAVE_STAT_ST_ATIM)
+       return pst->st_atim;
+#elif defined(HAVE_STAT_ST_ATIMENSEC)
+       struct timespec ret;
+       ret.tv_sec = pst->st_atime;
+       ret.tv_nsec = pst->st_atimensec;
+       return ret;
+#else
+#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT 
+#endif
+#endif
+}
+
+struct timespec get_mtimespec(SMB_STRUCT_STAT *pst)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+       struct timespec ret;
+
+       /* Old system - no ns timestamp. */
+       ret.tv_sec = pst->st_mtime;
+       ret.tv_nsec = 0;
+       return ret;
+#else
+#if defined(HAVE_STAT_ST_MTIM)
+       return pst->st_mtim;
+#elif defined(HAVE_STAT_ST_MTIMENSEC)
+       struct timespec ret;
+       ret.tv_sec = pst->st_mtime;
+       ret.tv_nsec = pst->st_mtimensec;
+       return ret;
+#else
+#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT 
+#endif
+#endif
+}
+
+struct timespec get_ctimespec(SMB_STRUCT_STAT *pst)
+{
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+       struct timespec ret;
+
+       /* Old system - no ns timestamp. */
+       ret.tv_sec = pst->ctime;
+       ret.tv_nsec = 0;
+       return ret;
+#else
+#if defined(HAVE_STAT_ST_CTIM)
+       return pst->st_ctim;
+#elif defined(HAVE_STAT_ST_CTIMENSEC)
+       struct timespec ret;
+       ret.tv_sec = pst->st_ctime;
+       ret.tv_nsec = pst->st_ctimensec;
+       return ret;
+#else
+#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT 
+#endif
+#endif
+}
+
+#if 0
+/****************************************************************************
+ Return the best approximation to a 'create time' under UNIX from a stat
+ structure.
+****************************************************************************/
+
+struct timespec get_create_timespec(SMB_STRUCT_STAT *st,BOOL fake_dirs)
+{
+       time_t ret, ret1;
+
+       if(S_ISDIR(st->st_mode) && fake_dirs) {
+               return (time_t)315493200L;          /* 1/1/1980 */
+       }
+    
+       ret = MIN(st->st_ctime, st->st_mtime);
+       ret1 = MIN(ret, st->st_atime);
+
+       if(ret1 != (time_t)0) {
+               return ret1;
+       }
+
+       /*
+        * One of ctime, mtime or atime was zero (probably atime).
+        * Just return MIN(ctime, mtime).
+        */
+       return ret;
+}
+#endif
index ee7d4314eef66d9a83ddca96fb745355f9342653..859a92a61e3c293253aeac82286e6be6f09effb6 100644 (file)
 
 struct change_data {
        time_t last_check_time; /* time we last checked this entry */
-#ifdef HAVE_STAT_HIRES_TIMESTAMPS
-       struct timespec modify_time;
-       struct timespec status_time;
-#else
-       time_t modify_time; /* Info from the directory we're monitoring. */ 
-       time_t status_time; /* Info from the directory we're monitoring. */
-#endif
+       struct timespec modify_time; /* Info from the directory we're monitoring. */
+       struct timespec status_time; /* Info from the directory we're monitoring. */
        time_t total_time; /* Total time of all directory entries - don't care if it wraps. */
        unsigned int num_entries; /* Zero or the number of files in the directory. */
        unsigned int mode_sum;
@@ -37,13 +32,8 @@ struct change_data {
 };
 
 
-#ifdef HAVE_STAT_HIRES_TIMESTAMPS
 /* Compare struct timespec. */
 #define TIMESTAMP_NEQ(x, y) (((x).tv_sec != (y).tv_sec) || ((x).tv_nsec != (y).tv_nsec))
-#else
-/* Compare time_t . */
-#define TIMESTAMP_NEQ(x, y) ((x) != (y))
-#endif
 
 /****************************************************************************
  Create the hash we will use to determine if the contents changed.
@@ -66,13 +56,8 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
        if(SMB_VFS_STAT(conn,path, &st) == -1)
                return False;
 
-#ifdef HAVE_STAT_HIRES_TIMESTAMPS
-       data->modify_time = st.st_mtim;
-       data->status_time = st.st_ctim;
-#else
-       data->modify_time = st.st_mtime;
-       data->status_time = st.st_ctime;
-#endif
+       data->modify_time = get_mtimespec(&st);
+       data->status_time = get_ctimespec(&st);
 
        if (old_data) {
                /*