[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [cdt-dev] Starter.exe
|
Hi,
This approach worked for me. I have two different starter.exes -- one for
cygwin, one for normal NT. Since I know which invocations are cygwin, it
works out.
As a funny aside, one of our engineers here who is the cygwin owner but
hates it with a passion seems to be calling me the king of the gross hacks
at the same time that he is amazingly pleased that it just works and he did
not actually have to do anything. Never underestimate the power of
someone's ability to rely on other people doing the dirty work.
No one will likely ever care, but I've put the source code at the end in
case anyone comes up against this at some point. Mail archives can be
wonderful things once in a while and no one else should have to go through
this.
Thanks!
-Chris
/* cygstarter.c
*
* This is an interface bewtween eclipse's spawner.dll and
* cygwin applications that correctly converts CTRL_C_EVENT to
* SIGINT.
*
* As a practical matter this only works on windows NT platforms
* (cygwin has a different pid to dwProessId mapping on non NT
* platforms) and is only known to work on cygwin 1.1.8-2.
*/
#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <mingw/tchar.h>
#include <signal.h>
// #define DEBUG_MONITOR
#define MAX_CMD_LINE_LENGTH (1024)
int main(int argc, TCHAR* argv[]) {
char szCmdLine[MAX_CMD_LINE_LENGTH] = { 0 };
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi = { 0 };
DWORD dwExitCode = 0;
#ifdef DEBUG_MONITOR
int currentPID = GetCurrentProcessId();
char buffer[MAX_CMD_LINE_LENGTH];
#endif
BOOL exitProc = FALSE;
HANDLE waitEvent;
HANDLE h[3];
BOOL f;
LPTSTR lpMsgBuf;
int i;
// Make sure that we've been passed the right number of arguments
if (argc < 5) {
_tprintf(_TEXT("Usage: %s (Three InheritableEventHandles)
(CommandLineToSpawn)\n"),
argv[0]);
return(0);
}
// Construct the full command line
for (i = 4; i < argc; i++) {
if(sizeof(szCmdLine) > (_tcslen(szCmdLine) + _tcslen(argv[i])))
{
_tcscat(szCmdLine, argv[i]);
_tcscat(szCmdLine, _TEXT(" "));
}
#ifdef DBUG_MONITOR
else
OutputDebugString("Command line is too long\n");
#endif
}
waitEvent = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[2]);
h[0] = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[1]);
h[2] = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[3]); // This is a
terminate event
#ifdef DEBUG_MONITOR
sprintf(buffer, "starter start command: %s\n", szCmdLine);
OutputDebugString(buffer);
#endif
// OutputDebugString(szCmdLine);
// Spawn the other processes as part of this Process Group
f = CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE,
0, NULL, NULL, &si, &pi);
if (f)
{
SetEvent(waitEvent); // Means thar process has been spawned
CloseHandle(pi.hThread);
h[1] = pi.hProcess;
while(!exitProc)
{
// Wait for the spawned-process to die or for the event
// indicating that the processes should be forcibly killed.
switch (WaitForMultipleObjects(3, h, FALSE, INFINITE))
{
case WAIT_OBJECT_0 + 0: // Send Ctrl-C
#ifdef DEBUG_MONITOR
sprintf(buffer, "starter (PID %i) received CTRL-C event\n", currentPID);
OutputDebugString(buffer);
#endif
kill( pi.dwProcessId, SIGINT );
SetEvent(waitEvent);
break;
case WAIT_OBJECT_0 + 1: // App terminated normally
// Make it's exit code our exit code
#ifdef DEBUG_MONITOR
sprintf(buffer, "starter: launched process has been terminated(PID
%i)\n", currentPID);
OutputDebugString(buffer);
#endif
GetExitCodeProcess(pi.hProcess, &dwExitCode);
exitProc = TRUE;
break;
case WAIT_OBJECT_0 + 2: // Kill
#ifdef DEBUG_MONITOR
sprintf(buffer, "starter received KILL event (PID %i)\n", currentPID);
OutputDebugString(buffer);
#endif
kill( pi.dwProcessId, SIGINT );
TerminateProcess(h[1], 0);
exitProc = TRUE;
break;
default:
// Unexpected code
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
OutputDebugString(lpMsgBuf);
// Free the buffer.
LocalFree( lpMsgBuf );
exitProc = TRUE;
break;
}
}
CloseHandle(pi.hProcess);
}
CloseHandle(waitEvent);
CloseHandle(h[0]);
CloseHandle(h[2]);
return(dwExitCode);
}
//////////////////////////////// End of File //////////////////////////////////