util.c: Made write_pidfile write the correct PID on MinGW/Msys

This workaround fixes an issue on MinGW/Msys regarding the Perl
testsuite scripts not being able to signal or control the server
processes. The MinGW Perl runtime only sees the Msys processes and
their corresponding PIDs, but sockfilt (and other servers) wrote the
Windows PID into their PID-files. Since this PID is useless to the
testsuite, the write_pidfile function was changed to search for the
Msys PID and write that into the PID-file.
This commit is contained in:
Marc Hoersken 2013-04-06 00:40:25 +02:00
parent bf7a270e0b
commit eeefcdff54

View File

@ -55,6 +55,10 @@
#define EINVAL 22 /* errno.h value */
#endif
#if __MINGW32__
#include <TlHelp32.h>
#endif
#if defined(ENABLE_IPV6) && defined(__MINGW32__)
const struct in6_addr in6addr_any = {{ IN6ADDR_ANY_INIT }};
#endif
@ -248,6 +252,58 @@ int wait_ms(int timeout_ms)
return r;
}
#ifdef __MINGW32__
/* WORKAROUND
*
* These functions make it possible to get the Msys PID instead of the
* Windows PID assigned to the current process. This is done by walking up
* to the Msys sh.exe process that launched the shadow Windows processes.
*
* Usually an Msys process would result in following process tree:
* sh.exe <-- waiting Windows process, but running Msys process
* \
* <proc>.exe <-- waiting Windows process
* \
* <proc>.exe <-- running Windows process
*
* Attention: This may not be true for all Msys processes.
*/
static pid_t getpid_msys(void)
{
PROCESSENTRY32 entry;
HANDLE snapshot;
DWORD pid;
BOOL walk;
pid = (DWORD)getpid();
entry.dwSize = sizeof(PROCESSENTRY32);
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, pid);
if(snapshot != INVALID_HANDLE_VALUE) {
walk = TRUE;
while(walk) {
if(Process32First(snapshot, &entry)) {
do {
if(pid == entry.th32ProcessID) {
if(!strcmp(entry.szExeFile, "sh.exe")) {
walk = FALSE;
break;
}
pid = entry.th32ParentProcessID;
break;
}
} while (Process32Next(snapshot, &entry));
}
}
CloseHandle(snapshot);
}
return (pid_t)pid;
}
#define getpid() getpid_msys()
#endif
int write_pidfile(const char *filename)
{
FILE *pidfile;