summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2021-10-15 18:53:55 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2021-10-15 18:54:49 -0700
commit074cbe590bb5f9d4be7334162e0803264bf5717d (patch)
tree0c95c04744c2321bcc0108f67c9eaa6c784681de
parent08b103ff4da9be30ea90e5a04b4ccea694f18ed3 (diff)
downloaddiffutils-074cbe590bb5f9d4be7334162e0803264bf5717d.tar.gz
diff: fix timezone bug on Solaris
Problem reported by Vladimir Marek (bug#51228). * NEWS: Mention this. * src/context.c (print_context_label): Pass localtz to nstrftime, instead of always passing 0. * src/diff.c (main) [!HAVE_TM_GMTOFF]: Initialize localtz if time_format uses %z. * src/diff.h (localtz): New decl. * tests/Makefile.am (TESTS): Add timezone. * tests/timezone: New test.
-rw-r--r--NEWS6
-rw-r--r--src/context.c2
-rw-r--r--src/diff.c3
-rw-r--r--src/diff.h7
-rw-r--r--tests/Makefile.am1
-rwxr-xr-xtests/timezone14
6 files changed, 32 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 3de0810..105a7df 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,12 @@ GNU diffutils NEWS -*- outline -*-
* Noteworthy changes in release ?.? (????-??-??) [?]
+** Bug fixes
+
+ diff -c and -u no longer output incorrect timezones in headers
+ on platforms like Solaris where struct tm lacks tm_gmtoff.
+ [bug#51228 introduced in 3.4]
+
* Noteworthy changes in release 3.8 (2021-08-01) [stable]
diff --git a/src/context.c b/src/context.c
index b3cfa7d..adcfdb3 100644
--- a/src/context.c
+++ b/src/context.c
@@ -52,7 +52,7 @@ print_context_label (char const *mark,
INT_STRLEN_BOUND (time_t) + 11)];
struct tm const *tm = localtime (&inf->stat.st_mtime);
int nsec = get_stat_mtime_ns (&inf->stat);
- if (! (tm && nstrftime (buf, sizeof buf, time_format, tm, 0, nsec)))
+ if (! (tm && nstrftime (buf, sizeof buf, time_format, tm, localtz, nsec)))
{
verify (TYPE_IS_INTEGER (time_t));
if (LONG_MIN <= TYPE_MINIMUM (time_t)
diff --git a/src/diff.c b/src/diff.c
index fedc7df..0961afb 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -729,6 +729,9 @@ main (int argc, char **argv)
#else
time_format = "%Y-%m-%d %H:%M:%S %z";
#endif
+#if !HAVE_TM_GMTOFF
+ localtz = tzalloc (getenv ("TZ"));
+#endif
}
else
{
diff --git a/src/diff.h b/src/diff.h
index d65c1da..34caa37 100644
--- a/src/diff.h
+++ b/src/diff.h
@@ -155,6 +155,13 @@ XTERN bool ignore_file_name_case;
(--no-dereference). */
XTERN bool no_dereference_symlinks;
+/* Local timezone for 'c' output headers, if needed. */
+#if HAVE_TM_GMTOFF
+# define localtz 0 /* Placeholder since localtz is never needed. */
+#else
+XTERN timezone_t localtz;
+#endif
+
/* File labels for '-c' output headers (--label). */
XTERN char *file_label[2];
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 83a7c9d..d98df82 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -22,6 +22,7 @@ TESTS = \
strcoll-0-names \
filename-quoting \
strip-trailing-cr \
+ timezone \
colors
XFAIL_TESTS = large-subopt
diff --git a/tests/timezone b/tests/timezone
new file mode 100755
index 0000000..52b9e18
--- /dev/null
+++ b/tests/timezone
@@ -0,0 +1,14 @@
+#!/bin/sh
+# In diff 3.4 through 3.8, this would output the wrong timezone on Solaris.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+
+fail=0
+
+echo a >a || fail=1
+case $(LC_ALL=C TZ=EST5 diff -u /dev/null a) in
+ *' -0500'*) ;;
+ *) fail=1 ;;
+esac
+
+Exit $fail