I've pushed this patch using Gnulib's stat-time instead of doing the check for struct stat members ourselves.
I tested 'ls' changes against Coreutils and 'rcp' changes with a NetBSD VM. Collin
>From 4b73be3eb2d764c2b2c7ca7afb19e0f88d24f45a Mon Sep 17 00:00:00 2001 From: Collin Funk <collin.fu...@gmail.com> Date: Mon, 2 Sep 2024 20:34:54 -0700 Subject: [PATCH] maint: Use stat-time from Gnulib. * bootstrap.conf (gnulib_modules): Add stat-time. * configure.ac: Prefer Gnulib checks for struct stat. * libls/cmp.c (off_cmp): New function. (modcmp, acccmp, statcmp, sizecmp): Use functions from stat-time. * src/rcp.c (write_stat_time): Likewise. --- bootstrap.conf | 1 + configure.ac | 10 ----- libls/cmp.c | 104 ++++++++++--------------------------------------- src/rcp.c | 36 +++++++---------- 4 files changed, 35 insertions(+), 116 deletions(-) diff --git a/bootstrap.conf b/bootstrap.conf index 4da15428..9ceb8616 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -93,6 +93,7 @@ signal size_max snprintf socklen +stat-time stdarg stdbool stdint diff --git a/configure.ac b/configure.ac index 7722bbcd..6e3c86b9 100644 --- a/configure.ac +++ b/configure.ac @@ -723,16 +723,6 @@ IU_CHECK_MEMBERS([struct sockaddr.sa_len], , , #include <sys/socket.h>]) IU_CHECK_MEMBERS([struct hostent.h_addr_list], , , [#include <netdb.h>]) -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 <sys/types.h> - #include <sys/stat.h>]) - # OpenSolaris does not use a union for `struct tftphdr.th_u'. As a # consequence `struct tftphdr.th_stuff' is a macro resolving to a # `ushort_t'. BSD and Linux produce `char *'. diff --git a/libls/cmp.c b/libls/cmp.c index 661ffb3e..a416d913 100644 --- a/libls/cmp.c +++ b/libls/cmp.c @@ -58,6 +58,9 @@ #include "ls.h" #include "extern.h" +#include "stat-time.h" +#include "timespec.h" + int namecmp (const FTSENT *a, const FTSENT *b) { @@ -73,32 +76,9 @@ 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 || -#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 || -#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)); + int diff = timespec_cmp (get_stat_mtime (b->fts_statp), + get_stat_mtime (a->fts_statp)); + return diff ? diff : namecmp (a, b); } int @@ -110,32 +90,9 @@ revmodcmp (const FTSENT *a, const FTSENT *b) int acccmp (const FTSENT *a, const FTSENT *b) { - 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 || -#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)); + int diff = timespec_cmp (get_stat_atime (b->fts_statp), + get_stat_atime (a->fts_statp)); + return diff ? diff : namecmp (a, b); } int @@ -147,32 +104,9 @@ revacccmp (const FTSENT *a, const FTSENT *b) int statcmp (const FTSENT *a, const FTSENT *b) { - 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 || -#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)); + int diff = timespec_cmp (get_stat_ctime (b->fts_statp), + get_stat_ctime (a->fts_statp)); + return diff ? diff : namecmp (a, b); } int @@ -181,15 +115,17 @@ revstatcmp (const FTSENT *a, const FTSENT *b) return (-statcmp (a, b)); } +static int +off_cmp (off_t a, off_t b) +{ + return (a > b) - (a < b); +} + int sizecmp (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 (namecmp (a, b)); + int diff = off_cmp (b->fts_statp->st_size, a->fts_statp->st_size); + return diff ? diff : namecmp (a, b); } int diff --git a/src/rcp.c b/src/rcp.c index 101f9563..6e30aefe 100644 --- a/src/rcp.c +++ b/src/rcp.c @@ -87,6 +87,10 @@ #include <error.h> #include <xalloc.h> +#include "intprops.h" +#include "stat-time.h" +#include "timespec.h" + typedef struct { int cnt; @@ -693,29 +697,17 @@ tolocal (int argc, char *argv[]) } static int -write_stat_time (int fd, struct stat *stat) +write_stat_time (int fd, struct stat *st) { - char buf[4 * sizeof (long) * 3 + 2]; - time_t a_sec, m_sec; - long a_usec = 0, m_usec = 0; - - 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_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", - m_sec, m_usec, a_sec, a_usec); - return write (fd, buf, strlen (buf)); + /* 'T' + 4 integers + 3 spaces + '\n' + '\0'. */ + char buffer[4 * INT_STRLEN_BOUND (intmax_t) + 1 + 3 + 2]; + struct timespec atime = get_stat_atime (st); + struct timespec mtime = get_stat_mtime (st); + int len = sprintf (buffer, "T%jd %jd %jd %jd\n", (intmax_t) mtime.tv_sec, + (intmax_t) (mtime.tv_nsec / 1000), + (intmax_t) atime.tv_sec, + (intmax_t) (mtime.tv_nsec / 1000)); + return write (fd, buffer, len); } void -- 2.46.0