summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2006-02-10 01:43:33 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:10:01 -0500
commit687e5be25e6090cf73867c3e08dab6a381c0adbc (patch)
tree69f3b79fc39b88b7e0843b9019099e70915dd5c1 /source3
parente97ad44d55895d6f5d269b2c316329cbf66e15ac (diff)
downloadsamba-687e5be25e6090cf73867c3e08dab6a381c0adbc.tar.gz
samba-687e5be25e6090cf73867c3e08dab6a381c0adbc.tar.bz2
samba-687e5be25e6090cf73867c3e08dab6a381c0adbc.zip
r13423: Write wrapper functions (and configure tests) so we can
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)
Diffstat (limited to 'source3')
-rw-r--r--source3/configure.in39
-rw-r--r--source3/lib/time.c102
-rw-r--r--source3/smbd/notify_hash.c23
3 files changed, 145 insertions, 19 deletions
diff --git a/source3/configure.in b/source3/configure.in
index 6dedbd3441..9774479acb 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -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)
diff --git a/source3/lib/time.c b/source3/lib/time.c
index f87e53fef5..b6a22a3098 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -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
diff --git a/source3/smbd/notify_hash.c b/source3/smbd/notify_hash.c
index ee7d4314ee..859a92a61e 100644
--- a/source3/smbd/notify_hash.c
+++ b/source3/smbd/notify_hash.c
@@ -23,13 +23,8 @@
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) {
/*