Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 6654754

Browse files
peffgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3f419d4 commit 6654754

File tree

4 files changed

+45
-0
lines changed

4 files changed

+45
-0
lines changed

Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@ all::
342342
# Define DEFAULT_HELP_FORMAT to "man", "info" or "html"
343343
# (defaults to "man") if you want to have a different default when
344344
# "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.
345348

346349
GIT-VERSION-FILE: FORCE
347350
@$(SHELL_PATH) ./GIT-VERSION-GEN
@@ -1464,6 +1467,11 @@ ifneq (,$(XDL_FAST_HASH))
14641467
BASIC_CFLAGS += -DXDL_FAST_HASH
14651468
endif
14661469

1470+
ifdef GMTIME_UNRELIABLE_ERRORS
1471+
COMPAT_OBJS += compat/gmtime.o
1472+
BASIC_CFLAGS += -DGMTIME_UNRELIABLE_ERRORS
1473+
endif
1474+
14671475
ifeq ($(TCLTK_PATH),)
14681476
NO_TCLTK = NoThanks
14691477
endif

compat/gmtime.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ ifeq ($(uname_S),FreeBSD)
189189
endif
190190
PYTHON_PATH = /usr/local/bin/python
191191
HAVE_PATHS_H = YesPlease
192+
GMTIME_UNRELIABLE_ERRORS = UnfortunatelyYes
192193
endif
193194
ifeq ($(uname_S),OpenBSD)
194195
NO_STRCASESTR = YesPlease

git-compat-util.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,4 +697,11 @@ void warn_on_inaccessible(const char *path);
697697
/* Get the passwd entry for the UID of the current process. */
698698
struct passwd *xgetpwuid_self(void);
699699

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+
700707
#endif

0 commit comments

Comments
 (0)