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

Reply via email to