Subject: fixing PR 23214
To: None <tech-toolchain@netbsd.org>
From: Chuck Silvers <chuq@chuq.com>
List: tech-toolchain
Date: 10/25/2003 21:22:35
--/9DWx/yDrRhgMJTb
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

what do people think of the attached patch as a fix for PR 23214?

-Chuck

--/9DWx/yDrRhgMJTb
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="diff.cross-stat"

Index: tools/compat/config.h.in
===================================================================
RCS file: /cvsroot/src/tools/compat/config.h.in,v
retrieving revision 1.30
diff -u -r1.30 config.h.in
--- tools/compat/config.h.in	25 Jul 2003 03:21:16 -0000	1.30
+++ tools/compat/config.h.in	25 Oct 2003 22:55:41 -0000
@@ -40,6 +40,7 @@
 #undef HAVE_STRUCT_DIRENT_D_NAMLEN
 #undef HAVE_STRUCT_STAT_ST_FLAGS
 #undef HAVE_STRUCT_STAT_ST_GEN
+#undef HAVE_STRUCT_STAT_ST_ATIMESPEC
 #undef HAVE_STRUCT_STAT_ST_BIRTHTIME
 #undef HAVE_STRUCT_STAT_ST_ATIM
 #undef HAVE_STRUCT_STAT_ST_MTIMENSEC
Index: tools/compat/configure
===================================================================
RCS file: /cvsroot/src/tools/compat/configure,v
retrieving revision 1.41
diff -u -r1.41 configure
--- tools/compat/configure	26 Jul 2003 20:23:59 -0000	1.41
+++ tools/compat/configure	25 Oct 2003 22:55:48 -0000
@@ -5613,6 +5613,99 @@
 
 
 fi
+echo "$as_me:$LINENO: checking for struct stat.st_atimespec" >&5
+echo $ECHO_N "checking for struct stat.st_atimespec... $ECHO_C" >&6
+if test "${ac_cv_member_struct_stat_st_atimespec+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+
+int
+main ()
+{
+static struct stat ac_aggr;
+if (ac_aggr.st_atimespec)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_atimespec=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/stat.h>
+
+int
+main ()
+{
+static struct stat ac_aggr;
+if (sizeof ac_aggr.st_atimespec)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_member_struct_stat_st_atimespec=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_stat_st_atimespec=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_atimespec" >&5
+echo "${ECHO_T}$ac_cv_member_struct_stat_st_atimespec" >&6
+if test $ac_cv_member_struct_stat_st_atimespec = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_ATIMESPEC 1
+_ACEOF
+
+
+fi
 echo "$as_me:$LINENO: checking for struct stat.st_birthtime" >&5
 echo $ECHO_N "checking for struct stat.st_birthtime... $ECHO_C" >&6
 if test "${ac_cv_member_struct_stat_st_birthtime+set}" = set; then
Index: tools/compat/configure.ac
===================================================================
RCS file: /cvsroot/src/tools/compat/configure.ac,v
retrieving revision 1.40
diff -u -r1.40 configure.ac
--- tools/compat/configure.ac	26 Jul 2003 20:24:00 -0000	1.40
+++ tools/compat/configure.ac	25 Oct 2003 22:55:49 -0000
@@ -83,7 +83,7 @@
 [#include <sys/types.h>
 #include <dirent.h>])
 AC_CHECK_MEMBERS([struct stat.st_flags, struct stat.st_gen,
-	struct stat.st_birthtime, struct stat.st_atim,
+	struct stat.st_atimespec, struct stat.st_birthtime, struct stat.st_atim,
 	struct stat.st_mtimensec],,, [#include <sys/stat.h>])
 AC_CHECK_MEMBERS(struct statfs.f_iosize,,, [#include <sys/mount.h>])
 
Index: usr.bin/stat/stat.c
===================================================================
RCS file: /cvsroot/src/usr.bin/stat/stat.c,v
retrieving revision 1.13
diff -u -r1.13 stat.c
--- usr.bin/stat/stat.c	25 Jul 2003 03:21:17 -0000	1.13
+++ usr.bin/stat/stat.c	25 Oct 2003 22:55:49 -0000
@@ -46,6 +46,7 @@
 #else  /* HAVE_CONFIG_H */
 #define HAVE_STRUCT_STAT_ST_FLAGS 1
 #define HAVE_STRUCT_STAT_ST_GEN 1
+#define HAVE_STRUCT_STAT_ST_ATIMESPEC 1
 #define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
 #define HAVE_STRUCT_STAT_ST_MTIMENSEC 1
 #define HAVE_DEVNAME 1
@@ -543,14 +544,16 @@
 	char smode[12], sid[12], path[PATH_MAX + 4];
 	struct passwd *pw;
 	struct group *gr;
-	const struct timespec *tsp;
-	struct timespec ts;
 	struct tm *tm;
-	int l, small, formats;
+	time_t secs;
+	long nsecs;
+	int l, small, formats, gottime;
 
-	tsp = NULL;
 	formats = 0;
 	small = 0;
+	gottime = 0;
+	secs = 0;
+	nsecs = 0;
 
 	/*
 	 * First, pick out the data and tweak it based on hilo or
@@ -664,26 +667,39 @@
 			ofmt = FMTF_UNSIGNED;
 		break;
 	case SHOW_st_atime:
-		tsp = &st->st_atimespec;
+		gottime = 1;
+		secs = st->st_atime;
+#ifdef HAVE_STRUCT_STAT_ST_ATIMESPEC
+		nsecs = st->st_atimespec.tv_nsec;
+#endif
 		/* FALLTHROUGH */
 	case SHOW_st_mtime:
-		if (tsp == NULL)
-			tsp = &st->st_mtimespec;
+		if (!gottime) {
+			secs = st->st_mtime;
+#ifdef HAVE_STRUCT_STAT_ST_ATIMESPEC
+			nsecs = st->st_mtimespec.tv_nsec;
+#endif
+		}
 		/* FALLTHROUGH */
 	case SHOW_st_ctime:
-		if (tsp == NULL)
-			tsp = &st->st_ctimespec;
+		if (!gottime) {
+			secs = st->st_ctime;
+#ifdef HAVE_STRUCT_STAT_ST_ATIMESPEC
+			nsecs = st->st_ctimespec.tv_nsec;
+#endif
+		}
 		/* FALLTHROUGH */
 #if HAVE_STRUCT_STAT_ST_BIRTHTIME
 	case SHOW_st_btime:
-		if (tsp == NULL)
-			tsp = &st->st_birthtimespec;
+		if (!gottime) {
+			secs = st->st_birthtimespec.tv_sec;
+			nsecs = st->st_birthtimespec.tv_nsec;
+		}
 #endif /* HAVE_STRUCT_STAT_ST_BIRTHTIME */
-		ts = *tsp;		/* copy so we can muck with it */
-		small = (sizeof(ts.tv_sec) == 4);
-		data = ts.tv_sec;
+		small = (sizeof(secs) == 4);
+		data = secs;
 		small = 1;
-		tm = localtime(&ts.tv_sec);
+		tm = localtime(&secs);
 		(void)strftime(path, sizeof(path), timefmt, tm);
 		sdata = path;
 		formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX |
@@ -887,7 +903,7 @@
 				(void)strcat(lfmt, tmp);
 			}
 			(void)strcat(lfmt, "d");
-			return (snprintf(buf, blen, lfmt, ts.tv_sec));
+			return (snprintf(buf, blen, lfmt, secs));
 		}
 
 		/*
@@ -930,13 +946,13 @@
 		 * less significant figures.
 		 */
 		for (; prec < 9; prec++)
-			ts.tv_nsec /= 10;
+			nsecs /= 10;
 
 		/*
 		 * Use the format, and then tack on any zeroes that
 		 * might be required to make up the requested precision.
 		 */
-		l = snprintf(buf, blen, lfmt, ts.tv_sec, ts.tv_nsec);
+		l = snprintf(buf, blen, lfmt, secs, nsecs);
 		for (; prec > 9 && l < blen; prec--, l++)
 			(void)strcat(buf, "0");
 		return (l);

--/9DWx/yDrRhgMJTb--