702
return strcasecmp(*ea, *eb);
703
}
704
705
+struct pinfo_t {
706
+ struct pinfo_t *next;
707
+ pid_t pid;
708
+ HANDLE proc;
709
+} pinfo_t;
710
+struct pinfo_t *pinfo = NULL;
711
+CRITICAL_SECTION pinfo_cs;
712
+
713
static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env,
714
const char *dir,
715
int prepend_cmd, int fhin, int fhout, int fherr)
802
return -1;
803
}
804
CloseHandle(pi.hThread);
797
- return (pid_t)pi.hProcess;
805
+
806
+ /*
807
+ * The process ID is the human-readable identifier of the process
808
+ * that we want to present in log and error messages. The handle
809
+ * is not useful for this purpose. But we cannot close it, either,
810
+ * because it is not possible to turn a process ID into a process
811
+ * handle after the process terminated.
812
+ * Keep the handle in a list for waitpid.
813
+ */
814
+ EnterCriticalSection(&pinfo_cs);
815
+ {
816
+ struct pinfo_t *info = xmalloc(sizeof(struct pinfo_t));
817
+ info->pid = pi.dwProcessId;
818
+ info->proc = pi.hProcess;
819
+ info->next = pinfo;
820
+ pinfo = info;
821
+ }
822
+ LeaveCriticalSection(&pinfo_cs);
823
+
824
+ return (pid_t)pi.dwProcessId;
825
}
826
827
static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env,
1545
return strbuf_detach(&buf, NULL);
1546
}
1547
1548
+pid_t waitpid(pid_t pid, int *status, unsigned options)
1549
+{
1550
+ HANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION,
1551
+ FALSE, pid);
1552
+ if (!h) {
1553
+ errno = ECHILD;
1554
+ return -1;
1555
+ }
1556
+
1557
+ if (options == 0) {
1558
+ struct pinfo_t **ppinfo;
1559
+ if (WaitForSingleObject(h, INFINITE) != WAIT_OBJECT_0) {
1560
+ CloseHandle(h);
1561
+ return 0;
1562
+ }
1563
+
1564
+ if (status)
1565
+ GetExitCodeProcess(h, (LPDWORD)status);
1566
+
1567
+ EnterCriticalSection(&pinfo_cs);
1568
+
1569
+ ppinfo = &pinfo;
1570
+ while (*ppinfo) {
1571
+ struct pinfo_t *info = *ppinfo;
1572
+ if (info->pid == pid) {
1573
+ CloseHandle(info->proc);
1574
+ *ppinfo = info->next;
1575
+ free(info);
1576
+ break;
1577
+ }
1578
+ ppinfo = &info->next;
1579
+ }
1580
+
1581
+ LeaveCriticalSection(&pinfo_cs);
1582
+
1583
+ CloseHandle(h);
1584
+ return pid;
1585
+ }
1586
+ CloseHandle(h);
1587
+
1588
+ errno = EINVAL;
1589
+ return -1;
1590
+}
1591
+
1592
#ifndef NO_MINGW_REPLACE_READDIR
1593
/* MinGW readdir implementation to avoid extra lstats for Git */
1594
struct mingw_DIR