From faff170bbc56b2dbf7def54d2e69dc91a1b3b66e Mon Sep 17 00:00:00 2001 From: Mats Erik Andersson Date: Thu, 17 Jul 2014 23:27:08 +0200 Subject: [PATCH] Handle access times in sub-seconds. Use contemporary and resonably portable techniques for microsecond or better accuracy in `struct stat'. --- ChangeLog | 26 +++++++++++ configure.ac | 10 +++- libls/cmp.c | 130 +++++++++++++++++++++++++++++++++++++++------------ src/rcp.c | 20 ++++---- 4 files changed, 145 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index 23115813..8d117846 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2014-07-16 Mats Erik Andersson + + Handle access timing in fractions of a second. + + * configure.ac (HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC) + (HAVE_STRUCT_STAT_ST_ATIM_TV_USEC, HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC) + (HAVE_STRUCT_STAT_ST_CTIM_TV_USEC, HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) + (HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC): Check for existing time field + for sub-second timing in `struct stat'. + (HAVE_STRUCT_STAT_ST_BLKSTAT): Make the macro functional! + + * libls/cmp.c (modcmp) [HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC] + [HAVE_STRUCT_STAT_ST_MTIM_TV_USEC]: Compare in sub-seconds. + (acccmp) [HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC] + [HAVE_STRUCT_STAT_ST_ATIM_TV_USEC]: Likewise. + (statmod) [HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC] + [HAVE_STRUCT_STAT_CT_MTIM_TV_USEC]: Likewise + (revmodcmp, revaccmp, revstatmod, revsizecmp): Replace code + by a simple sign change of modcmp(), acccmp(), etcetera. + + * src/rcp.c [HAVE_STAT_ST_MTIMESPEC || HAVE_STAT_ST_MTIME_USEC] + (write_stat_time): Remove unused and obsolete code. + [HAVE_STRUCT_STAT_ST_ATIM_NSEC || HAVE_STRUCT_STAT_ST_ATIM_USEC] + [HAVE_STRUCT_STAT_ST_MTIM_NSEC || HAVE_STRUCT_STAT_ST_MTIM_USEC] + (write_stat_time): Code portably for sub-second accuracy. + 2014-07-14 Mats Erik Andersson ftp: Hash command semantic. diff --git a/configure.ac b/configure.ac index 54fab009..135bff09 100644 --- a/configure.ac +++ b/configure.ac @@ -703,7 +703,15 @@ IU_CHECK_MEMBERS([struct sockaddr.sa_len], , , #include ]) IU_CHECK_MEMBERS([struct hostent.h_addr_list], , , [#include ]) -IU_CHECK_MEMBERS([struct stat.st_blksize]) +IU_CHECK_MEMBERS([struct stat.st_atim.tv_nsec, + struct stat.st_atim.tv_usec, + struct stat.st_blksize, + struct stat.st_ctim.tv_nsec, + struct stat.st_ctim.tv_usec, + struct stat.st_mtim.tv_nsec, + struct stat.st_mtim.tv_usec], , , + [#include + #include ]) # OpenSolaris does not use a union for `struct tftphdr.th_u'. As a # consequence `struct tftphdr.th_stuff' is a macro resolving to a diff --git a/libls/cmp.c b/libls/cmp.c index 80a62215..b3ff5057 100644 --- a/libls/cmp.c +++ b/libls/cmp.c @@ -74,9 +74,39 @@ revnamecmp (const FTSENT *a, const FTSENT *b) int modcmp (const FTSENT *a, const FTSENT *b) { - if (b->fts_statp->st_mtime > a->fts_statp->st_mtime) + if (b->fts_statp->st_mtime > a->fts_statp->st_mtime + || +#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC + ( b->fts_statp->st_mtime == a->fts_statp->st_mtime + && + b->fts_statp->st_mtim.tv_nsec > a->fts_statp->st_mtim.tv_nsec + ) +#elif defined HAVE_STRUCT_STAT_ST_MTIM_TV_USEC + ( b->fts_statp->st_mtime == a->fts_statp->st_mtime + && + b->fts_statp->st_mtim.tv_usec > a->fts_statp->st_mtim.tv_usec + ) +#else + 0 +#endif + ) return (1); - else if (b->fts_statp->st_mtime < a->fts_statp->st_mtime) + else if (b->fts_statp->st_mtime < a->fts_statp->st_mtime + || +#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC + ( b->fts_statp->st_mtime == a->fts_statp->st_mtime + && + b->fts_statp->st_mtim.tv_nsec < a->fts_statp->st_mtim.tv_nsec + ) +#elif defined HAVE_STRUCT_STAT_ST_MTIM_TV_USEC + ( b->fts_statp->st_mtime == a->fts_statp->st_mtime + && + b->fts_statp->st_mtim.tv_usec < a->fts_statp->st_mtim.tv_usec + ) +#else + 0 +#endif + ) return (-1); else return (namecmp (a, b)); @@ -85,20 +115,45 @@ modcmp (const FTSENT *a, const FTSENT *b) int revmodcmp (const FTSENT *a, const FTSENT *b) { - if (b->fts_statp->st_mtime > a->fts_statp->st_mtime) - return (-1); - else if (b->fts_statp->st_mtime < a->fts_statp->st_mtime) - return (1); - else - return (revnamecmp (a, b)); + return (- modcmp (a, b)); } int acccmp (const FTSENT *a, const FTSENT *b) { - if (b->fts_statp->st_atime > a->fts_statp->st_atime) + if (b->fts_statp->st_atime > a->fts_statp->st_atime + || +#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC + ( b->fts_statp->st_atime == a->fts_statp->st_atime + && + b->fts_statp->st_atim.tv_nsec > a->fts_statp->st_atim.tv_nsec + ) +#elif defined HAVE_STRUCT_STAT_ST_ATIM_TV_USEC + ( b->fts_statp->st_atime == a->fts_statp->st_atime + && + b->fts_statp->st_atim.tv_usec > a->fts_statp->st_atim.tv_usec + ) +#else + 0 +#endif + ) return (1); - else if (b->fts_statp->st_atime < a->fts_statp->st_atime) + else if (b->fts_statp->st_atime < a->fts_statp->st_atime + || +#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC + ( b->fts_statp->st_atime == a->fts_statp->st_atime + && + b->fts_statp->st_atim.tv_nsec < a->fts_statp->st_atim.tv_nsec + ) +#elif defined HAVE_STRUCT_STAT_ST_ATIM_TV_USEC + ( b->fts_statp->st_atime == a->fts_statp->st_atime + && + b->fts_statp->st_atim.tv_usec < a->fts_statp->st_atim.tv_usec + ) +#else + 0 +#endif + ) return (-1); else return (namecmp (a, b)); @@ -107,20 +162,45 @@ acccmp (const FTSENT *a, const FTSENT *b) int revacccmp (const FTSENT *a, const FTSENT *b) { - if (b->fts_statp->st_atime > a->fts_statp->st_atime) - return (-1); - else if (b->fts_statp->st_atime < a->fts_statp->st_atime) - return (1); - else - return (revnamecmp (a, b)); + return (- acccmp (a, b)); } int statcmp (const FTSENT *a, const FTSENT *b) { - if (b->fts_statp->st_ctime > a->fts_statp->st_ctime) + if (b->fts_statp->st_ctime > a->fts_statp->st_ctime + || +#ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC + ( b->fts_statp->st_ctime == a->fts_statp->st_ctime + && + b->fts_statp->st_ctim.tv_nsec > a->fts_statp->st_ctim.tv_nsec + ) +#elif defined HAVE_STRUCT_STAT_ST_CTIM_TV_USEC + ( b->fts_statp->st_ctime == a->fts_statp->st_ctime + && + b->fts_statp->st_ctim.tv_usec > a->fts_statp->st_ctim.tv_usec + ) +#else + 0 +#endif + ) return (1); - else if (b->fts_statp->st_ctime < a->fts_statp->st_ctime) + else if (b->fts_statp->st_ctime < a->fts_statp->st_ctime + || +#ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC + ( b->fts_statp->st_ctime == a->fts_statp->st_ctime + && + b->fts_statp->st_ctim.tv_nsec < a->fts_statp->st_ctim.tv_nsec + ) +#elif defined HAVE_STRUCT_STAT_ST_CTIM_TV_USEC + ( b->fts_statp->st_ctime == a->fts_statp->st_ctime + && + b->fts_statp->st_ctim.tv_usec < a->fts_statp->st_ctim.tv_usec + ) +#else + 0 +#endif + ) return (-1); else return (namecmp (a, b)); @@ -129,12 +209,7 @@ statcmp (const FTSENT *a, const FTSENT *b) int revstatcmp (const FTSENT *a, const FTSENT *b) { - if (b->fts_statp->st_ctime > a->fts_statp->st_ctime) - return (-1); - else if (b->fts_statp->st_ctime < a->fts_statp->st_ctime) - return (1); - else - return (revnamecmp (a, b)); + return (- statcmp (a, b)); } int @@ -151,10 +226,5 @@ sizecmp (const FTSENT *a, const FTSENT *b) int revsizecmp (const FTSENT *a, const FTSENT *b) { - if (b->fts_statp->st_size > a->fts_statp->st_size) - return (-1); - if (b->fts_statp->st_size < a->fts_statp->st_size) - return (1); - else - return (revnamecmp (a, b)); + return (- sizecmp (a, b)); } diff --git a/src/rcp.c b/src/rcp.c index 234beac0..d59c11fb 100644 --- a/src/rcp.c +++ b/src/rcp.c @@ -677,18 +677,18 @@ write_stat_time (int fd, struct stat *stat) time_t a_sec, m_sec; long a_usec = 0, m_usec = 0; -#ifdef HAVE_STAT_ST_MTIMESPEC - a_sec = stat->st_atimespec.ts_sec; - a_usec = stat->st_atimespec.ts_nsec / 1000; - m_sec = stat->st_mtimespec.ts_sec; - m_usec = stat->st_mtimespec.ts_nsec / 1000; -#else a_sec = stat->st_atime; +#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC + a_usec = stat->st_atim.tv_nsec / 1000; +#elif defined HAVE_STRUCT_STAT_ST_ATIM_TV_USEC + a_usec = stat->st_atim.tv_usec; +#endif + m_sec = stat->st_mtime; -# ifdef HAVE_STAT_ST_MTIME_USEC - a_usec = stat->st_atime_usec; - m_usec = stat->st_mtime_usec; -# endif +#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC + m_usec = stat->st_mtim.tv_nsec / 1000; +#elif defined HAVE_STRUCT_STAT_ST_MTIM_TV_USEC + m_usec = stat->st_mtim.tv_usec; #endif snprintf (buf, sizeof (buf), "T%ld %ld %ld %ld\n",