pull --rebase: Avoid spurious conflicts and reapplying unnecessary patches
[gitweb.git] / compat / mingw.c
index 162d1ff283e5e13adb108b1c65d7017ebb80cb55..ab65f77ab99500d99d24a9b7266669f37bb02cb2 100644 (file)
@@ -3,7 +3,7 @@
 #include <conio.h>
 #include "../strbuf.h"
 
-static int err_win_to_posix(DWORD winerr)
+int err_win_to_posix(DWORD winerr)
 {
        int error = ENOSYS;
        switch(winerr) {
@@ -140,12 +140,20 @@ int mingw_open (const char *filename, int oflags, ...)
        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;
-       winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
-       winTime /= 10000000;             /* Nano to seconds resolution */
-       return (time_t)winTime;
+       /* Windows to Unix Epoch conversion */
+       return winTime - 116444736000000000LL;
+}
+
+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.
@@ -281,19 +289,13 @@ int mkstemp(char *template)
 
 int gettimeofday(struct timeval *tv, void *tz)
 {
-       SYSTEMTIME st;
-       struct tm tm;
-       GetSystemTime(&st);
-       tm.tm_year = st.wYear-1900;
-       tm.tm_mon = st.wMonth-1;
-       tm.tm_mday = st.wDay;
-       tm.tm_hour = st.wHour;
-       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;
+       FILETIME ft;
+       long long hnsec;
+
+       GetSystemTimeAsFileTime(&ft);
+       hnsec = filetime_to_hnsec(&ft);
+       tv->tv_sec = hnsec / 10000000;
+       tv->tv_usec = (hnsec % 10000000) / 10;
        return 0;
 }
 
@@ -615,8 +617,8 @@ static int env_compare(const void *a, const void *b)
        return strcasecmp(*ea, *eb);
 }
 
-static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,
-                          int prepend_cmd)
+static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,
+                             int prepend_cmd, int fhin, int fhout, int fherr)
 {
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
@@ -652,9 +654,9 @@ static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,
        memset(&si, 0, sizeof(si));
        si.cb = sizeof(si);
        si.dwFlags = STARTF_USESTDHANDLES;
-       si.hStdInput = (HANDLE) _get_osfhandle(0);
-       si.hStdOutput = (HANDLE) _get_osfhandle(1);
-       si.hStdError = (HANDLE) _get_osfhandle(2);
+       si.hStdInput = (HANDLE) _get_osfhandle(fhin);
+       si.hStdOutput = (HANDLE) _get_osfhandle(fhout);
+       si.hStdError = (HANDLE) _get_osfhandle(fherr);
 
        /* concatenate argv, quoting args as we go */
        strbuf_init(&args, 0);
@@ -709,7 +711,14 @@ static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,
        return (pid_t)pi.hProcess;
 }
 
-pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env)
+static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,
+                          int prepend_cmd)
+{
+       return mingw_spawnve_fd(cmd, argv, env, prepend_cmd, 0, 1, 2);
+}
+
+pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env,
+                    int fhin, int fhout, int fherr)
 {
        pid_t pid;
        char **path = get_path_split();
@@ -731,13 +740,15 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env)
                                pid = -1;
                        }
                        else {
-                               pid = mingw_spawnve(iprog, argv, env, 1);
+                               pid = mingw_spawnve_fd(iprog, argv, env, 1,
+                                                      fhin, fhout, fherr);
                                free(iprog);
                        }
                        argv[0] = argv0;
                }
                else
-                       pid = mingw_spawnve(prog, argv, env, 0);
+                       pid = mingw_spawnve_fd(prog, argv, env, 0,
+                                              fhin, fhout, fherr);
                free(prog);
        }
        free_path_split(path);