Skip to content

Commit a6d15bc

Browse files
j6tgitster
authored andcommitted
Do not use date.c:tm_to_time_t() from compat/mingw.c
To implement gettimeofday(), a broken-down UTC time was requested from the system using GetSystemTime(), then tm_to_time_t() was used to convert it to a time_t because it does not look at the current timezone, which mktime() would do. Use GetSystemTimeAsFileTime() and a different conversion path to avoid this back-reference from the compatibility layer to the generic code. Signed-off-by: Johannes Sixt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 44626dc commit a6d15bc

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

compat/mingw.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,20 @@ int mingw_open (const char *filename, int oflags, ...)
140140
return fd;
141141
}
142142

143-
static inline time_t filetime_to_time_t(const FILETIME *ft)
143+
/*
144+
* The unit of FILETIME is 100-nanoseconds since January 1, 1601, UTC.
145+
* Returns the 100-nanoseconds ("hekto nanoseconds") since the epoch.
146+
*/
147+
static inline long long filetime_to_hnsec(const FILETIME *ft)
144148
{
145149
long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
146-
winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
147-
winTime /= 10000000; /* Nano to seconds resolution */
148-
return (time_t)winTime;
150+
/* Windows to Unix Epoch conversion */
151+
return winTime - 116444736000000000LL;
152+
}
153+
154+
static inline time_t filetime_to_time_t(const FILETIME *ft)
155+
{
156+
return (time_t)(filetime_to_hnsec(ft) / 10000000);
149157
}
150158

151159
/* We keep the do_lstat code in a separate function to avoid recursion.
@@ -281,19 +289,13 @@ int mkstemp(char *template)
281289

282290
int gettimeofday(struct timeval *tv, void *tz)
283291
{
284-
SYSTEMTIME st;
285-
struct tm tm;
286-
GetSystemTime(&st);
287-
tm.tm_year = st.wYear-1900;
288-
tm.tm_mon = st.wMonth-1;
289-
tm.tm_mday = st.wDay;
290-
tm.tm_hour = st.wHour;
291-
tm.tm_min = st.wMinute;
292-
tm.tm_sec = st.wSecond;
293-
tv->tv_sec = tm_to_time_t(&tm);
294-
if (tv->tv_sec < 0)
295-
return -1;
296-
tv->tv_usec = st.wMilliseconds*1000;
292+
FILETIME ft;
293+
long long hnsec;
294+
295+
GetSystemTimeAsFileTime(&ft);
296+
hnsec = filetime_to_hnsec(&ft);
297+
tv->tv_sec = hnsec / 10000000;
298+
tv->tv_usec = (hnsec % 10000000) / 10;
297299
return 0;
298300
}
299301

0 commit comments

Comments
 (0)