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.
(This used to be commit 07132d8796a08aa71d6719cb07b5b2c999930632)

source3/configure.in
source3/lib/time.c
source3/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) {
                /*