[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 2/2] Work around GNU/Linux timestamp glitch
From: |
Paul Eggert |
Subject: |
[PATCH v2 2/2] Work around GNU/Linux timestamp glitch |
Date: |
Fri, 24 Mar 2023 14:08:11 -0700 |
Without this patch, Bash can hand out user-visible timestamps
that are out of order, because on GNU/Linux the 'time'
function uses a different clock than file timestamps
and the 'gettimeofday' function.
The out-of-order timestamps can lead to user-confusion.
https://sourceware.org/bugzilla/show_bug.cgi?id=30200
This fixes a bug reported against Bash in 2020 by felix
https://lists.gnu.org/archive/html/bug-bash/2020-04/msg00072.html
* include/posixtime.h (getnow): New function.
All calls to 'time' changed to use this function.
* support/man2html.c (print_sig): Prefer gettimeofday if available.
---
general.h | 2 +-
include/posixtime.h | 10 ++++++++++
lib/readline/history.c | 4 +++-
parse.y | 6 +++---
support/man2html.c | 8 +++++++-
5 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/general.h b/general.h
index fa57251a..2232fabd 100644
--- a/general.h
+++ b/general.h
@@ -242,7 +242,7 @@ typedef int sh_builtin_func_t (WORD_LIST *); /*
sh_wlist_func_t */
#endif /* SH_FUNCTION_TYPEDEF */
-#define NOW ((time_t) time ((time_t *) 0))
+#define NOW getnow ()
#define GETTIME(tv) gettimeofday(&(tv), NULL)
/* Some defines for calling file status functions. */
diff --git a/include/posixtime.h b/include/posixtime.h
index 319cb168..7b0fc035 100644
--- a/include/posixtime.h
+++ b/include/posixtime.h
@@ -52,6 +52,16 @@ struct timeval
extern int gettimeofday (struct timeval * restrict, void * restrict);
#endif
+static inline time_t
+getnow (void)
+{
+ /* Avoid time (NULL), which can disagree with gettimeofday and with
+ filesystem timestamps. */
+ struct timeval now;
+ gettimeofday (&now, 0);
+ return now.tv_sec;
+}
+
/* These exist on BSD systems, at least. */
#if !defined (timerclear)
# define timerclear(tvp) do { (tvp)->tv_sec = 0; (tvp)->tv_usec = 0; }
while (0)
diff --git a/lib/readline/history.c b/lib/readline/history.c
index 42580301..9dc90147 100644
--- a/lib/readline/history.c
+++ b/lib/readline/history.c
@@ -48,6 +48,7 @@
#include "history.h"
#include "histlib.h"
+#include "posixtime.h"
#include "xmalloc.h"
#if !defined (errno)
@@ -261,7 +262,8 @@ hist_inittime (void)
time_t t;
char ts[64], *ret;
- t = (time_t) time ((time_t *)0);
+ t = getnow ();
+
#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists
*/
snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
#else
diff --git a/parse.y b/parse.y
index b758756a..2a61eb8c 100644
--- a/parse.y
+++ b/parse.y
@@ -85,7 +85,7 @@ typedef void *alias_t;
# ifndef _MINIX
# include <sys/param.h>
# endif
-# include <time.h>
+# include "posixtime.h"
# if defined (TM_IN_SYS_TIME)
# include <sys/types.h>
# include <sys/time.h>
@@ -5976,7 +5976,7 @@ decode_prompt_string (char *string)
case '@':
case 'A':
/* Make the current time/date into a string. */
- (void) time (&the_time);
+ the_time = getnow ();
#if defined (HAVE_TZSET)
sv_tz ("TZ"); /* XXX -- just make sure */
#endif
@@ -6010,7 +6010,7 @@ decode_prompt_string (char *string)
if (string[1] != '{') /* } */
goto not_escape;
- (void) time (&the_time);
+ the_time = getnow ();
tm = localtime (&the_time);
string += 2; /* skip { */
t = string;
diff --git a/support/man2html.c b/support/man2html.c
index 58165796..61f05f10 100644
--- a/support/man2html.c
+++ b/support/man2html.c
@@ -452,8 +452,14 @@ print_sig(void)
struct tm *timetm;
time_t clock;
- datbuf[0] = '\0';
+#if HAVE_GETTIMEOFDAY
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ clock = tv.tv_sec;
+#else
clock = time(NULL);
+#endif
+ datbuf[0] = '\0';
timetm = localtime(&clock);
if (timetm)
strftime(datbuf, MED_STR_MAX, TIMEFORMAT, timetm);
--
2.39.2