Browse Source

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 <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Johannes Sixt 15 years ago committed by Junio C Hamano
parent
commit
a6d15bc335
  1. 36
      compat/mingw.c

36
compat/mingw.c

@ -140,12 +140,20 @@ int mingw_open (const char *filename, int oflags, ...)
return fd; return fd;
} }


static inline time_t filetime_to_time_t(const FILETIME *ft) /*
* The unit of FILETIME is 100-nanoseconds since January 1, 1601, UTC.
* Returns the 100-nanoseconds ("hekto nanoseconds") since the epoch.
*/
static inline long long filetime_to_hnsec(const FILETIME *ft)
{ {
long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime; long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */ /* Windows to Unix Epoch conversion */
winTime /= 10000000; /* Nano to seconds resolution */ return winTime - 116444736000000000LL;
return (time_t)winTime; }

static inline time_t filetime_to_time_t(const FILETIME *ft)
{
return (time_t)(filetime_to_hnsec(ft) / 10000000);
} }


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


int gettimeofday(struct timeval *tv, void *tz) int gettimeofday(struct timeval *tv, void *tz)
{ {
SYSTEMTIME st; FILETIME ft;
struct tm tm; long long hnsec;
GetSystemTime(&st);
tm.tm_year = st.wYear-1900; GetSystemTimeAsFileTime(&ft);
tm.tm_mon = st.wMonth-1; hnsec = filetime_to_hnsec(&ft);
tm.tm_mday = st.wDay; tv->tv_sec = hnsec / 10000000;
tm.tm_hour = st.wHour; tv->tv_usec = (hnsec % 10000000) / 10;
tm.tm_min = st.wMinute;
tm.tm_sec = st.wSecond;
tv->tv_sec = tm_to_time_t(&tm);
if (tv->tv_sec < 0)
return -1;
tv->tv_usec = st.wMilliseconds*1000;
return 0; return 0;
} }



Loading…
Cancel
Save