1
0
mirror of https://github.com/samba-team/samba.git synced 2025-07-31 20:22:15 +03:00

lib/util: Standardize use of st_[acm]time ns

Commit 810397f89a, and possibly others, broke the build for macOS and
other environments which don't have st_[acm]tim fields on 'struct stat'.

Multiple places in the codebase used the config.h values to determine
how to access the nanosecond or microsecond values of the stat
timestamps, so rather than add more, centralize them all into
lib/util/time.c.

Also allow pvfs_fileinfo.c to read nanosecond-granularity timestamps on
platforms where it didn't before, since its #if branches were not
complete.

Signed-off-by: Matthew DeVore <matvore@google.com>
Reviewed-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>

Autobuild-User(master): Volker Lendecke <vl@samba.org>
Autobuild-Date(master): Sat Aug 15 08:51:09 UTC 2020 on sn-devel-184
This commit is contained in:
Matthew DeVore
2020-08-04 17:49:42 -07:00
committed by Volker Lendecke
parent 9f7ef21e00
commit 53a1d034f3
7 changed files with 276 additions and 135 deletions

View File

@ -26,6 +26,7 @@
#include "system/passwd.h"
#include "system/filesys.h"
#include "lib/util/setid.h"
#include "lib/util/time.h"
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
@ -122,124 +123,6 @@ int sys_fcntl_int(int fd, int cmd, int arg)
return ret;
}
/****************************************************************************
Get/Set all the possible time fields from a stat struct as a timespec.
****************************************************************************/
static struct timespec get_atimespec(const 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_STRUCT_STAT_ST_MTIM_TV_NSEC)
struct timespec ret;
ret.tv_sec = pst->st_atim.tv_sec;
ret.tv_nsec = pst->st_atim.tv_nsec;
return ret;
#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
struct timespec ret;
ret.tv_sec = pst->st_atime;
ret.tv_nsec = pst->st_atimensec;
return ret;
#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
struct timespec ret;
ret.tv_sec = pst->st_atime;
ret.tv_nsec = pst->st_atime_n;
return ret;
#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
struct timespec ret;
ret.tv_sec = pst->st_atime;
ret.tv_nsec = pst->st_uatime * 1000;
return ret;
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
return pst->st_atimespec;
#else
#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
#endif
#endif
}
static struct timespec get_mtimespec(const 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_STRUCT_STAT_ST_MTIM_TV_NSEC)
struct timespec ret;
ret.tv_sec = pst->st_mtim.tv_sec;
ret.tv_nsec = pst->st_mtim.tv_nsec;
return ret;
#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
struct timespec ret;
ret.tv_sec = pst->st_mtime;
ret.tv_nsec = pst->st_mtimensec;
return ret;
#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
struct timespec ret;
ret.tv_sec = pst->st_mtime;
ret.tv_nsec = pst->st_mtime_n;
return ret;
#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
struct timespec ret;
ret.tv_sec = pst->st_mtime;
ret.tv_nsec = pst->st_umtime * 1000;
return ret;
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
return pst->st_mtimespec;
#else
#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
#endif
#endif
}
static struct timespec get_ctimespec(const struct stat *pst)
{
#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
struct timespec ret;
/* Old system - no ns timestamp. */
ret.tv_sec = pst->st_ctime;
ret.tv_nsec = 0;
return ret;
#else
#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
struct timespec ret;
ret.tv_sec = pst->st_ctim.tv_sec;
ret.tv_nsec = pst->st_ctim.tv_nsec;
return ret;
#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
struct timespec ret;
ret.tv_sec = pst->st_ctime;
ret.tv_nsec = pst->st_ctimensec;
return ret;
#elif defined(HAVE_STRUCT_STAT_ST_MTIME_N)
struct timespec ret;
ret.tv_sec = pst->st_ctime;
ret.tv_nsec = pst->st_ctime_n;
return ret;
#elif defined(HAVE_STRUCT_STAT_ST_UMTIME)
struct timespec ret;
ret.tv_sec = pst->st_ctime;
ret.tv_nsec = pst->st_uctime * 1000;
return ret;
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
return pst->st_ctimespec;
#else
#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
#endif
#endif
}
/****************************************************************************
Return the best approximation to a 'create time' under UNIX from a stat
structure.