date: recognize bogus FreeBSD gmtime output
Most gmtime implementations return a NULL value when they encounter an error (and this behavior is specified by ANSI C and POSIX). FreeBSD's implementation, however, will simply leave the "struct tm" untouched. Let's also recognize this and convert it to a NULL (with this patch, t4212 should pass on FreeBSD). Reported-by: René Scharfe <l.s.r@web.de> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
Apr 1, 2014 at 17:28 UTC
6654754779d2a90af91a9c6b93d7e4e7ee16cfab
4 files changed
+45
Makefile
+8
@@ -342,6 +342,9 @@ all::
342
# Define DEFAULT_HELP_FORMAT to "man", "info" or "html"
343
# (defaults to "man") if you want to have a different default when
344
# "git help" is called without a parameter specifying the format.
345
+#
346
+# Define GMTIME_UNRELIABLE_ERRORS if your gmtime() function does not
347
+# return NULL when it receives a bogus time_t.
348
349
GIT-VERSION-FILE: FORCE
350
@$(SHELL_PATH) ./GIT-VERSION-GEN
@@ -1464,6 +1467,11 @@ ifneq (,$(XDL_FAST_HASH))
1467
BASIC_CFLAGS += -DXDL_FAST_HASH
1468
endif
1469
1470
+ifdef GMTIME_UNRELIABLE_ERRORS
1471
+ COMPAT_OBJS += compat/gmtime.o
1472
+ BASIC_CFLAGS += -DGMTIME_UNRELIABLE_ERRORS
1473
+endif
1474
+
1475
ifeq ($(TCLTK_PATH),)
1476
NO_TCLTK = NoThanks
1477
endif
compat/gmtime.c
new
+29
@@ -0,0 +1,29 @@
1
+#include "../git-compat-util.h"
2
+#undef gmtime
3
+#undef gmtime_r
4
+
5
+struct tm *git_gmtime(const time_t *timep)
6
+{
7
+ static struct tm result;
8
+ return git_gmtime_r(timep, &result);
9
+}
10
+
11
+struct tm *git_gmtime_r(const time_t *timep, struct tm *result)
12
+{
13
+ struct tm *ret;
14
+
15
+ memset(result, 0, sizeof(*result));
16
+ ret = gmtime_r(timep, result);
17
+
18
+ /*
19
+ * Rather than NULL, FreeBSD gmtime simply leaves the "struct tm"
20
+ * untouched when it encounters overflow. Since "mday" cannot otherwise
21
+ * be zero, we can test this very quickly.
22
+ */
23
+ if (ret && !ret->tm_mday) {
24
+ ret = NULL;
25
+ errno = EOVERFLOW;
26
+ }
27
+
28
+ return ret;
29
+}
config.mak.uname
+1
@@ -189,6 +189,7 @@ ifeq ($(uname_S),FreeBSD)
189
endif
190
PYTHON_PATH = /usr/local/bin/python
191
HAVE_PATHS_H = YesPlease
192
+ GMTIME_UNRELIABLE_ERRORS = UnfortunatelyYes
193
endif
194
ifeq ($(uname_S),OpenBSD)
195
NO_STRCASESTR = YesPlease
git-compat-util.h
+7
@@ -697,4 +697,11 @@ void warn_on_inaccessible(const char *path);
697
/* Get the passwd entry for the UID of the current process. */
698
struct passwd *xgetpwuid_self(void);
699
700
+#ifdef GMTIME_UNRELIABLE_ERRORS
701
+struct tm *git_gmtime(const time_t *);
702
+struct tm *git_gmtime_r(const time_t *, struct tm *);
703
+#define gmtime git_gmtime
704
+#define gmtime_r git_gmtime_r
705
+#endif
706
+
707
#endif