Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlain Magloire2004-02-12 21:12:51 +0000
committerAlain Magloire2004-02-12 21:12:51 +0000
commitc2ba759a8cb1be0f2888ada5e71828b60926388b (patch)
treed5641e0b75031c4cfae0440d8edcf4a5551e4fde /core/org.eclipse.cdt.core.win32/library
parent385ac1b870575ff371cf0a8b4bc2558d14697d00 (diff)
downloadorg.eclipse.cdt-c2ba759a8cb1be0f2888ada5e71828b60926388b.tar.gz
org.eclipse.cdt-c2ba759a8cb1be0f2888ada5e71828b60926388b.tar.xz
org.eclipse.cdt-c2ba759a8cb1be0f2888ada5e71828b60926388b.zip
Update the starter/spawner to use named pipes.
Patch from alex.
Diffstat (limited to 'core/org.eclipse.cdt.core.win32/library')
-rw-r--r--core/org.eclipse.cdt.core.win32/library/Spawner.h20
-rw-r--r--core/org.eclipse.cdt.core.win32/library/SpawnerInputStream.h15
-rw-r--r--core/org.eclipse.cdt.core.win32/library/SpawnerOutputStream.h14
-rw-r--r--core/org.eclipse.cdt.core.win32/library/StdAfx.c10
-rw-r--r--core/org.eclipse.cdt.core.win32/library/StdAfx.h11
-rw-r--r--core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c277
-rw-r--r--core/org.eclipse.cdt.core.win32/library/iostream.c142
-rw-r--r--core/org.eclipse.cdt.core.win32/library/raise.c74
-rw-r--r--core/org.eclipse.cdt.core.win32/library/spawner.c17
-rw-r--r--core/org.eclipse.cdt.core.win32/library/starter/starter.cpp104
10 files changed, 479 insertions, 205 deletions
diff --git a/core/org.eclipse.cdt.core.win32/library/Spawner.h b/core/org.eclipse.cdt.core.win32/library/Spawner.h
index 3641bd88ca6..400452b4d5b 100644
--- a/core/org.eclipse.cdt.core.win32/library/Spawner.h
+++ b/core/org.eclipse.cdt.core.win32/library/Spawner.h
@@ -1,3 +1,17 @@
+/**********************************************************************
+ * Copyright (c) 2002-2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *
+ * Spawner.h
+ *
+ * This is a part of JNI implementation of spawner
+***********************************************************************/
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_eclipse_cdt_utils_spawner_Spawner */
@@ -40,9 +54,15 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor
(JNIEnv *, jobject, jint);
+// #define DEBUG_MONITOR
+
int interruptProcess(int pid);
+
#ifdef __cplusplus
}
#endif
+
+// #define DEBUG_MONITOR
+
#endif
diff --git a/core/org.eclipse.cdt.core.win32/library/SpawnerInputStream.h b/core/org.eclipse.cdt.core.win32/library/SpawnerInputStream.h
index 7ab967353eb..f0c484a8427 100644
--- a/core/org.eclipse.cdt.core.win32/library/SpawnerInputStream.h
+++ b/core/org.eclipse.cdt.core.win32/library/SpawnerInputStream.h
@@ -1,3 +1,18 @@
+/**********************************************************************
+ * Copyright (c) 2002-2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *
+ * SpawnerInputStream.h
+ *
+ * This is a part of JNI implementation of spawner
+***********************************************************************/
+
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_qnx_tools_utils_spawner_SpawnerInputStream */
diff --git a/core/org.eclipse.cdt.core.win32/library/SpawnerOutputStream.h b/core/org.eclipse.cdt.core.win32/library/SpawnerOutputStream.h
index 7470e533c9a..161e1b81236 100644
--- a/core/org.eclipse.cdt.core.win32/library/SpawnerOutputStream.h
+++ b/core/org.eclipse.cdt.core.win32/library/SpawnerOutputStream.h
@@ -1,3 +1,17 @@
+/**********************************************************************
+ * Copyright (c) 2002-2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ *
+ * SpawnerOutputStream.h
+ *
+ * This is a part of JNI implementation of spawner
+***********************************************************************/
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_qnx_tools_utils_spawner_SpawnerOutputStream */
diff --git a/core/org.eclipse.cdt.core.win32/library/StdAfx.c b/core/org.eclipse.cdt.core.win32/library/StdAfx.c
index dc7550edf6d..318bc9214a6 100644
--- a/core/org.eclipse.cdt.core.win32/library/StdAfx.c
+++ b/core/org.eclipse.cdt.core.win32/library/StdAfx.c
@@ -1,12 +1,16 @@
/**********************************************************************
- * Copyright (c) 2002,2003 QNX Software Systems and others.
+ * Copyright (c) 2002-2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
+ * are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
+ * http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ *
+ * StdAfx.c
+ *
+ * This is a part of JNI implementation of spawner
***********************************************************************/
// stdafx.cpp : source file that includes just the standard includes
// spawner.pch will be the pre-compiled header
diff --git a/core/org.eclipse.cdt.core.win32/library/StdAfx.h b/core/org.eclipse.cdt.core.win32/library/StdAfx.h
index 3ec5e93c719..4b427db00f4 100644
--- a/core/org.eclipse.cdt.core.win32/library/StdAfx.h
+++ b/core/org.eclipse.cdt.core.win32/library/StdAfx.h
@@ -1,13 +1,18 @@
/**********************************************************************
- * Copyright (c) 2002,2003 QNX Software Systems and others.
+ * Copyright (c) 2002-2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
+ * are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
+ * http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ *
+ * StdAfx.h
+ *
+ * This is a part of JNI implementation of spawner
***********************************************************************/
+
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
diff --git a/core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c b/core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c
index a78d83b2766..4379580730b 100644
--- a/core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c
+++ b/core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c
@@ -1,59 +1,76 @@
/**********************************************************************
- * Copyright (c) 2002,2003 QNX Software Systems and others.
+ * Copyright (c) 2002-2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
+ * are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
+ * http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
-***********************************************************************/
-/*
+ *
* Win32ProcessEx.c
*
* This is a JNI implementation of spawner
- */
+***********************************************************************/
+
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
#include <process.h>
#include "Spawner.h"
+
+
+#include "jni.h"
+#include "io.h"
+
+#define PIPE_SIZE 512 // Size of pipe buffer
+#define MAX_CMD_SIZE 2049 // Maximum size of command line
+#define MAX_ENV_SIZE 4096 // Initial size of environment block
+#define PIPE_NAME_LENGTH 100 // Size of pipe name buffer
+#define PIPE_TIMEOUT 10000 // Default time-out value, in milliseconds.
-#include "jni.h"
-#include "io.h"
-
-// #define DEBUG_MONITOR
-
-#define PIPE_SIZE 512
-#define MAX_CMD_SIZE 2049
-#define MAX_ENV_SIZE 4096
-
-#define MAX_PROCS (100)
+#define MAX_PROCS (100) // Maximum number of simultaneiously runnig processes
+// Theses are VM helpers
typedef JNIEXPORT void * (JNICALL * JVM_GetThreadInterruptEvent)();
typedef JNIEXPORT char * (JNICALL * JVM_NativePath)(const char *);
+// Process description block. Should be created for each launched process
typedef struct _procInfo {
int pid; // Process ID
- int uid; // quasi-unique process ID
+ int uid; // quasi-unique process ID; we have to create it to avoid duplicated pid
+ // (actually this impossible from OS point of view but it is still possible
+ // a clash of new created and already finished process with one and the same PID.
+ // 3 events connected to this process (see starter)
HANDLE eventBreak;
HANDLE eventWait;
HANDLE eventTerminate;
} procInfo_t, * pProcInfo_t;
-static int procCounter = 0;
+static int procCounter = 0; // Number of running processes
+// This is a VM helper
JNIEXPORT void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg);
-pProcInfo_t createProcInfo();
-pProcInfo_t findProcInfo(int pid);
+
+// Creates _procInfo block for every launched procss
+pProcInfo_t createProcInfo();
+
+// Find process description for this pid
+pProcInfo_t findProcInfo(int pid);
+
+// We launch separate thread for each project to trap it termination
unsigned int _stdcall waitProcTermination(void* pv) ;
+
+// This is a helper function to prevent losing of quotatin marks
static int copyTo(char * target, const char * source, int cpyLenght, int availSpace);
-static void cleanUpProcBlock(pProcInfo_t pCurProcInfo);
+// Use this function to clean project descriptor and return it to the pool of available blocks.
+static void cleanUpProcBlock(pProcInfo_t pCurProcInfo);
+// Signal codes
typedef enum {
SIG_NOOP,
SIG_HUP,
@@ -65,20 +82,27 @@ typedef enum {
extern CRITICAL_SECTION cs;
-extern TCHAR path[MAX_PATH];
+extern TCHAR path[MAX_PATH]; // Directory where spawner.dll is located
-static HMODULE hVM = NULL;
+static HMODULE hVM = NULL; // VM handler
static pProcInfo_t pInfo = NULL;
+static int nCounter = 0; // We use it to build unique synchronisation object names
+/////////////////////////////////////////////////////////////////////////////////////
+// Launcher; launchess process and traps its termination
+// Arguments: (see Spawner.java)
+// [in] cmdarray - array of command line elements
+// [in] envp - array of environment variables
+// [in] dir - working directory
+// [out] channels - streams handlers
+/////////////////////////////////////////////////////////////////////////////////////
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
(JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir, jintArray channels)
{
-
- HANDLE hread[3], hwrite[3];
- SECURITY_ATTRIBUTES sa;
+ HANDLE stdHandles[3];
PROCESS_INFORMATION pi = {0};
STARTUPINFO si;
DWORD flags = 0;
@@ -91,6 +115,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
jsize nCmdTokens = 0;
jsize nEnvVars = 0;
int i;
+ DWORD pid = GetCurrentProcessId();
int nPos;
pProcInfo_t pCurProcInfo;
DWORD dwThreadId;
@@ -100,6 +125,10 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
#ifdef DEBUG_MONITOR
char buffer[1000];
#endif
+ int nLocalCounter;
+ char inPipeName[PIPE_NAME_LENGTH];
+ char outPipeName[PIPE_NAME_LENGTH];
+ char errPipeName[PIPE_NAME_LENGTH];
if((HIBYTE(LOWORD(GetVersion()))) & 0x80)
{
@@ -113,25 +142,39 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
return 0;
}
- sa.nLength = sizeof(sa);
- sa.lpSecurityDescriptor = 0;
- sa.bInheritHandle = TRUE;
-
- memset(hread, 0, sizeof(hread));
- memset(hwrite, 0, sizeof(hwrite));
- if (!(CreatePipe(&hread[0], &hwrite[0], &sa, PIPE_SIZE) &&
- CreatePipe(&hread[1], &hwrite[1], &sa, PIPE_SIZE) &&
- CreatePipe(&hread[2], &hwrite[2], &sa, PIPE_SIZE)))
- {
- CloseHandle(hread[0]);
- CloseHandle(hread[1]);
- CloseHandle(hread[2]);
- CloseHandle(hwrite[0]);
- CloseHandle(hwrite[1]);
- CloseHandle(hwrite[2]);
+ ZeroMemory(stdHandles, sizeof(stdHandles));
+
+ // Create pipe names
+ EnterCriticalSection(&cs);
+ sprintf(inPipeName, "\\\\.\\pipe\\stdin%08i%010i", pid, nCounter);
+ sprintf(outPipeName, "\\\\.\\pipe\\stdout%08i%010i", pid, nCounter);
+ sprintf(errPipeName, "\\\\.\\pipe\\stderr%08i%010i", pid, nCounter);
+ nLocalCounter = nCounter;
+ ++nCounter;
+ LeaveCriticalSection(&cs);
+
+
+ if ((INVALID_HANDLE_VALUE == (stdHandles[0] = CreateNamedPipe(inPipeName, PIPE_ACCESS_OUTBOUND,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+ PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, PIPE_TIMEOUT, NULL))) ||
+ (INVALID_HANDLE_VALUE == (stdHandles[1] = CreateNamedPipe(outPipeName, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+ PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, PIPE_TIMEOUT, NULL))) ||
+ (INVALID_HANDLE_VALUE == (stdHandles[2] = CreateNamedPipe(errPipeName, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+ PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, PIPE_TIMEOUT, NULL)))) {
+ CloseHandle(stdHandles[0]);
+ CloseHandle(stdHandles[1]);
+ CloseHandle(stdHandles[2]);
ThrowByName(env, "java/io/IOException", "CreatePipe");
return 0;
- }
+ }
+
+#ifdef DEBUG_MONITOR
+ sprintf(buffer, "Opened pipes: %s, %s, %s\n", inPipeName, outPipeName, errPipeName);
+ OutputDebugString(buffer);
+#endif
+
nCmdTokens = (*env) -> GetArrayLength(env, cmdarray);
nEnvVars = (*env) -> GetArrayLength(env, envp);
@@ -144,17 +187,18 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
return 0;
}
-
+ // Construct starter's command line
sprintf(eventBreakName, "SABreak%p", pCurProcInfo);
sprintf(eventWaitName, "SAWait%p", pCurProcInfo);
sprintf(eventTerminateName, "SATerm%p", pCurProcInfo);
pCurProcInfo -> eventBreak = CreateEvent(NULL, TRUE, FALSE, eventBreakName);
ResetEvent(pCurProcInfo -> eventBreak);
pCurProcInfo -> eventWait = CreateEvent(NULL, TRUE, FALSE, eventWaitName);
+ ResetEvent(pCurProcInfo -> eventWait);
pCurProcInfo -> eventTerminate = CreateEvent(NULL, TRUE, FALSE, eventTerminateName);
ResetEvent(pCurProcInfo -> eventTerminate);
- nPos = sprintf(szCmdLine, "%sstarter.exe %s %s %s ", path, eventBreakName, eventWaitName, eventTerminateName);
+ nPos = sprintf(szCmdLine, "%sstarter.exe %i %i %s %s %s ", path, pid, nLocalCounter, eventBreakName, eventWaitName, eventTerminateName);
// Prepare command line
for(i = 0; i < nCmdTokens; ++i)
@@ -229,21 +273,16 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
}
- memset(&si, 0, sizeof(si));
+ ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
- si.dwFlags |= STARTF_USESTDHANDLES;
si.dwFlags |= STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; // Processes in the Process Group are hidden
- si.hStdInput = hread[0];
- si.hStdOutput = hwrite[1];
- si.hStdError = hwrite[2];
-
- SetHandleInformation(hwrite[0], HANDLE_FLAG_INHERIT, FALSE);
- SetHandleInformation(hread[1], HANDLE_FLAG_INHERIT, FALSE);
- SetHandleInformation(hread[2], HANDLE_FLAG_INHERIT, FALSE);
+ SetHandleInformation(stdHandles[0], HANDLE_FLAG_INHERIT, FALSE);
+ SetHandleInformation(stdHandles[1], HANDLE_FLAG_INHERIT, FALSE);
+ SetHandleInformation(stdHandles[2], HANDLE_FLAG_INHERIT, FALSE);
flags = CREATE_NEW_CONSOLE;
flags |= CREATE_NO_WINDOW;
@@ -251,14 +290,15 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
#ifdef DEBUG_MONITOR
OutputDebugString(szCmdLine);
#endif
-
+ // launches starter; we need it to create another console group to correctly process
+ // emulation of SYSint signal (Ctrl-C)
ret = CreateProcess(0, /* executable name */
- szCmdLine, /* command line */
+ szCmdLine, /* command line */
0, /* process security attribute */
0, /* thread security attribute */
- TRUE, /* inherits system handles */
+ FALSE, /* inherits system handles */
flags, /* normal attached process */
- envBlk, /* environment block */
+ envBlk, /* environment block */
cwd, /* change to the new current directory */
&si, /* (in) startup information */
&pi); /* (out) process information */
@@ -270,18 +310,13 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
free(szEnvBlock);
- CloseHandle(hread[0]);
- CloseHandle(hwrite[1]);
- CloseHandle(hwrite[2]);
-
-
- if (!ret)
+ if (!ret) // Launching error
{
LPTSTR lpMsgBuf;
- CloseHandle(hwrite[0]);
- CloseHandle(hread[1]);
- CloseHandle(hread[2]);
+ CloseHandle(stdHandles[0]);
+ CloseHandle(stdHandles[1]);
+ CloseHandle(stdHandles[2]);
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
@@ -327,18 +362,19 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
}
else
{
-#ifdef DEBUG_MONITOR
- sprintf(buffer, "Process %i created\n", pi.dwProcessId);
- OutputDebugString(buffer);
-#endif
ret = (long)(pCurProcInfo -> uid);
- file_handles[0] = (int)hwrite[0];
- file_handles[1] = (int)hread[1];
- file_handles[2] = (int)hread[2];
+
+ // Prepare stream handlers to return to java program
+ file_handles[0] = (int)stdHandles[0];
+ file_handles[1] = (int)stdHandles[1];
+ file_handles[2] = (int)stdHandles[2];
(*env) -> SetIntArrayRegion(env, channels, 0, 3, file_handles);
}
CloseHandle(h[1]);
LeaveCriticalSection(&cs);
+#ifdef DEBUG_MONITOR
+ OutputDebugString("Process started\n");
+#endif
}
@@ -348,6 +384,13 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
}
+/////////////////////////////////////////////////////////////////////////////////////
+// Launcher; just launches process and don't care about it any more
+// Arguments: (see Spawner.java)
+// [in] cmdarray - array of command line elements
+// [in] envp - array of environment variables
+// [in] dir - working directory
+/////////////////////////////////////////////////////////////////////////////////////
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
(JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir)
{
@@ -389,7 +432,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
{
if(0 > (nCpyLen = copyTo(szCmdLine + nPos, str, len, MAX_CMD_SIZE - nPos)))
{
- ThrowByName(env, "java/io/IOException", "Too long command line");
+ ThrowByName(env, "java/io/Exception", "Too long command line");
return 0;
}
nPos += nCpyLen;
@@ -418,7 +461,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
szEnvBlock = (char *)realloc(szEnvBlock, nBlkSize);
if(NULL == szEnvBlock)
{
- ThrowByName(env, "java/io/IOException", "Not enough memory");
+ ThrowByName(env, "java/io/Exception", "Not enough memory");
return 0;
}
}
@@ -446,7 +489,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
}
- memset(&si, 0, sizeof(si));
+ ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
@@ -472,7 +515,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
free(cwd);
free(szEnvBlock);
- if (!ret)
+ if (!ret) // error
{
LPTSTR lpMsgBuf;
@@ -494,6 +537,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
}
else
{
+ // Clean-up
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
ret = (long)pi.dwProcessId; //hProcess;
@@ -505,6 +549,12 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
}
+/////////////////////////////////////////////////////////////////////////////////////
+// Emulation of the signal raising
+// Arguments: (see Spawner.java)
+// [in] uid - unique process ID
+// [in] signal - signal to raise
+/////////////////////////////////////////////////////////////////////////////////////
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise
(JNIEnv * env, jobject process, jint uid, jint signal)
{
@@ -570,13 +620,18 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise
}
-
-
+
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Wait for process termination
+// Arguments: (see Spawner.java)
+// [in] uid - unique process ID
+/////////////////////////////////////////////////////////////////////////////////////
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor
(JNIEnv * env, jobject process, jint uid)
-{
- long exit_code;
- int what=0;
+{
+ long exit_code;
+ int what=0;
HANDLE hProc;
pProcInfo_t pCurProcInfo = findProcInfo(uid);
@@ -590,25 +645,31 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor
what = WaitForSingleObject(hProc, INFINITE);
-
+
if (what == WAIT_OBJECT_0)
- {
- GetExitCodeProcess(hProc, &exit_code);
+ {
+ GetExitCodeProcess(hProc, &exit_code);
}
if(hProc)
CloseHandle(hProc);
- return exit_code;
-}
-
-
-
+ return exit_code;
+}
+
+
+
// Utilities
+/////////////////////////////////////////////////////////////////////////////////////
+// Throws Java exception (will be trapped by VM).
+// Arguments:
+// [in] name - name of exception class
+// [in] message to assign thi event
+/////////////////////////////////////////////////////////////////////////////////////
JNIEXPORT void JNICALL
ThrowByName(JNIEnv *env, const char *name, const char *msg)
{
@@ -624,6 +685,11 @@ ThrowByName(JNIEnv *env, const char *name, const char *msg)
+/////////////////////////////////////////////////////////////////////////////////////
+// Create process description block.
+// Arguments: no
+// Return : pointer to the process descriptor
+/////////////////////////////////////////////////////////////////////////////////////
pProcInfo_t createProcInfo()
{
int i;
@@ -634,7 +700,7 @@ pProcInfo_t createProcInfo()
if(NULL == pInfo)
{
pInfo = malloc(sizeof(procInfo_t) * MAX_PROCS);
- memset(pInfo, 0, sizeof(procInfo_t) * MAX_PROCS);
+ ZeroMemory(pInfo, sizeof(procInfo_t) * MAX_PROCS);
}
for(i = 0; i < MAX_PROCS; ++i)
@@ -653,6 +719,11 @@ pProcInfo_t createProcInfo()
return p;
}
+/////////////////////////////////////////////////////////////////////////////////////
+// Using unique process ID finds process descriptor
+// Arguments: no
+// Return : pointer to the process descriptor
+/////////////////////////////////////////////////////////////////////////////////////
pProcInfo_t findProcInfo(int uid)
{
int i;
@@ -672,6 +743,11 @@ pProcInfo_t findProcInfo(int uid)
return p;
}
+/////////////////////////////////////////////////////////////////////////////////////
+// Cleans up vacant process descriptor
+// Arguments:
+// pCurProcInfo - pointer to descriptor to clean up
+// Return : no
void cleanUpProcBlock(pProcInfo_t pCurProcInfo)
{
if(0 != pCurProcInfo -> eventBreak)
@@ -693,11 +769,16 @@ void cleanUpProcBlock(pProcInfo_t pCurProcInfo)
pCurProcInfo -> pid = 0;
}
+/////////////////////////////////////////////////////////////////////////////////////
+// Running in separae thread and waiting for the process termination
+// Arguments:
+// pv - (int)pv is a pid
+// Return : always 0
+/////////////////////////////////////////////////////////////////////////////////////
unsigned int _stdcall waitProcTermination(void* pv)
{
int i;
int pid = (int)pv;
- DWORD rc = 0;
#ifdef DEBUG_MONITOR
char buffer[1000];
#endif
@@ -742,7 +823,15 @@ unsigned int _stdcall waitProcTermination(void* pv)
return 0;
}
-// Return number of bytes in target or -1 in case of error
+/////////////////////////////////////////////////////////////////////////////////////
+// Use this utility program to process correctly quotation marks in the command line
+// Arguments:
+// target - string to copy to
+// source - string to copy from
+// cpyLength - copy length
+// availSpace - size of the target buffer
+// Return :number of bytes used in target, or -1 in case of error
+/////////////////////////////////////////////////////////////////////////////////////
int copyTo(char * target, const char * source, int cpyLength, int availSpace)
{
BOOL bSlash = FALSE;
diff --git a/core/org.eclipse.cdt.core.win32/library/iostream.c b/core/org.eclipse.cdt.core.win32/library/iostream.c
index faae3c11120..2c091176775 100644
--- a/core/org.eclipse.cdt.core.win32/library/iostream.c
+++ b/core/org.eclipse.cdt.core.win32/library/iostream.c
@@ -1,23 +1,25 @@
/**********************************************************************
- * Copyright (c) 2002,2003 QNX Software Systems and others.
+ * Copyright (c) 2002-2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
+ * are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
+ * http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ *
+ * raise.c
+ *
+ * This is a part of JNI implementation of spawner
+ * Includes implementation of JNI methods (see Spawner.java)
***********************************************************************/
-/*
- * This is a JNI implementation of access to standard i/o streams
- */
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
+#include "spawner.h"
#include "SpawnerInputStream.h"
#include "SpawnerOutputStream.h"
-
#include "jni.h"
#include "io.h"
@@ -37,35 +39,87 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
{
BYTE tmpBuf[BUFF_SIZE];
int nBuffOffset = 0;
+#ifdef DEBUG_MONITOR
+ char buffer[1000];
+#endif
+ OVERLAPPED overlapped;
+ overlapped.Offset = 0;
+ overlapped.OffsetHigh = 0;
+ overlapped.hEvent = CreateEvent(NULL, // no security attribute
+ TRUE, // manual-reset event
+ TRUE, // initial state = signaled
+ NULL); // unnamed event object
+
+ if(NULL == overlapped.hEvent) {
+ LPTSTR lpMsgBuf;
+ 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
+ );
+
+ ThrowByName(env, "java/io/IOException", lpMsgBuf);
+ }
+
+#ifdef DEBUG_MONITOR
+ sprintf(buffer, "Start read %i\n", fd);
+ OutputDebugString(buffer);
+#endif
while(len > nBuffOffset)
{
int nNumberOfBytesToRead = min(len - nBuffOffset, BUFF_SIZE);
int nNumberOfBytesRead;
- if(0 == ReadFile((HANDLE)fd, tmpBuf, nNumberOfBytesToRead, &nNumberOfBytesRead, NULL ))
+ if(0 == ReadFile((HANDLE)fd, tmpBuf, nNumberOfBytesToRead, &nNumberOfBytesRead, &overlapped ))
{
- LPTSTR lpMsgBuf;
int err = GetLastError();
+ if(err == ERROR_IO_PENDING)
+ {
+ // asynchronous i/o is still in progress
+ // check on the results of the asynchronous read
+ if(GetOverlappedResult((HANDLE)fd, &overlapped,
+ &nNumberOfBytesRead, TRUE))
+ err = 0;
+ // if there was a problem ...
+ else
+ err = GetLastError();
+ }
if(err == ERROR_BROKEN_PIPE) // Pipe was closed
- return 0;
- if(err != ERROR_MORE_DATA) // Otherwise error means just that there are more data
- { // than buffer can accept
- FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- err,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL
- );
-
- ThrowByName(env, "java/io/IOException", lpMsgBuf);
- LocalFree( lpMsgBuf );
- return 0;
+ break;
+ if(err != 0)
+ {
+ LPTSTR lpMsgBuf;
+#ifdef DEBUG_MONITOR
+ char buffer[200];
+ sprintf(buffer, "Read failed - %i, error %i\n", fd, err);
+ OutputDebugString(buffer);
+#endif
+ if(err != ERROR_MORE_DATA) // Otherwise error means just that there are more data
+ { // than buffer can accept
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+
+ ThrowByName(env, "java/io/IOException", lpMsgBuf);
+ LocalFree( lpMsgBuf );
+ nBuffOffset = 0;
+ break;
+ }
}
}
if(nNumberOfBytesRead > 0)
@@ -76,6 +130,11 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
if(nNumberOfBytesRead != nNumberOfBytesToRead)
break;
}
+ CloseHandle(overlapped.hEvent);
+#ifdef DEBUG_MONITOR
+ sprintf(buffer, "End read %i\n", fd);
+ OutputDebugString(buffer);
+#endif
return nBuffOffset; // This is a real full readed length
}
@@ -88,7 +147,19 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0
(JNIEnv * env, jobject proc, jint fd)
{
- return (CloseHandle((HANDLE)fd) ? 0 : -1);
+ int rc;
+#ifdef DEBUG_MONITOR
+ char buffer[1000];
+ sprintf(buffer, "Close %i\n", fd);
+ OutputDebugString(buffer);
+#endif
+ DisconnectNamedPipe((HANDLE)fd);
+ rc = (CloseHandle((HANDLE)fd) ? 0 : -1);
+#ifdef DEBUG_MONITOR
+ sprintf(buffer, "Closed %i\n", fd);
+ OutputDebugString(buffer);
+#endif
+ return (rc ? GetLastError() : 0);
}
/*
@@ -102,6 +173,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_wr
BYTE tmpBuf[BUFF_SIZE];
int nBuffOffset = 0;
+
while(len > nBuffOffset)
{
int nNumberOfBytesToWrite = min(len - nBuffOffset, BUFF_SIZE);
@@ -139,5 +211,17 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_wr
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0
(JNIEnv * env, jobject proc, jint fd)
{
- return (CloseHandle((HANDLE)fd) ? 0 : -1);
+ int rc;
+#ifdef DEBUG_MONITOR
+ char buffer[1000];
+ sprintf(buffer, "Close %i\n", fd);
+ OutputDebugString(buffer);
+#endif
+ DisconnectNamedPipe((HANDLE)fd);
+ rc = (CloseHandle((HANDLE)fd) ? 0 : -1);
+#ifdef DEBUG_MONITOR
+ sprintf(buffer, "Closed %i\n", fd);
+ OutputDebugString(buffer);
+#endif
+ return (rc ? GetLastError() : 0);
}
diff --git a/core/org.eclipse.cdt.core.win32/library/raise.c b/core/org.eclipse.cdt.core.win32/library/raise.c
index ebe0172f585..b4305e222f4 100644
--- a/core/org.eclipse.cdt.core.win32/library/raise.c
+++ b/core/org.eclipse.cdt.core.win32/library/raise.c
@@ -1,16 +1,17 @@
/**********************************************************************
- * Copyright (c) 2002,2003 QNX Software Systems and others.
+ * Copyright (c) 2002-2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
+ * are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
+ * http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ *
+ * raise.c
+ *
+ * This is a part of JNI implementation of spawner
***********************************************************************/
-/*
- * This is a JNI implementation of spawner
- */
#include "stdafx.h"
#include "Spawner.h"
@@ -19,10 +20,17 @@
extern void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg);
-// #define DEBUG_MONITOR
static HWND consoleHWND;
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Check if window is a console of process with pid
+// Arguments:
+// hwnd - window handler
+// arg - process PID
+// Return : TRUE if yes
+/////////////////////////////////////////////////////////////////////////////////////
static BOOL CALLBACK
find_child_console (HWND hwnd, LPARAM arg)
{
@@ -46,35 +54,13 @@ find_child_console (HWND hwnd, LPARAM arg)
return TRUE;
}
-/*
-JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise__Ljava_lang_Object_2
- (JNIEnv * env, jobject process, jobject jpid)
-{
- jint pid;
- jclass integerClass = (*env) -> FindClass(env, "java/lang/Integer");
- jmethodID intValue;
- if(NULL == integerClass) {
- ThrowByName(env, "java/lang/IOException", "Cannot find Integer class");
- return -1;
- }
- if(!((*env) -> IsInstanceOf(env, jpid, integerClass))) {
- ThrowByName(env, "java/lang/IOException", "Wrong argument");
- return -1;
- }
-
- intValue = (*env) -> GetMethodID(env, integerClass, "intValue", "()I");
- if(NULL == intValue) {
- ThrowByName(env, "java/lang/IOException", "Cannot find intValue method in Integer class");
- return -1;
- }
-
- pid = (*env) -> CallIntMethod(env, jpid, intValue);
-
- return interruptProcess(pid);
-
-}
-*/
+/////////////////////////////////////////////////////////////////////////////////////
+// Function implements interrupt process (Ctrl-C emulation)
+// Arguments:
+// pid - process' pid
+// Return : 0 if OK or error code
+/////////////////////////////////////////////////////////////////////////////////////
int interruptProcess(int pid)
{
#ifdef DEBUG_MONITOR
@@ -89,10 +75,13 @@ int interruptProcess(int pid)
sprintf(buffer, "Try to interrupt process %i\n", pid);
OutputDebugString(buffer);
#endif
+ // Find console
EnumWindows (find_child_console, (LPARAM) pid);
- if(NULL != consoleHWND)
+ if(NULL != consoleHWND) // Yes, we found out it
{
+ // We are going to switch focus to console,
+ // send Ctrl-C and then restore focus
BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0);
/* Fake Ctrl-C for SIGINT, and Ctrl-Break for SIGQUIT. */
BYTE vk_c_code = 'C';
@@ -100,7 +89,7 @@ int interruptProcess(int pid)
BYTE c_scan_code = (BYTE) MapVirtualKey (vk_c_code, 0);
BYTE break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
HWND foreground_window;
-
+
foreground_window = GetForegroundWindow ();
if (foreground_window)
@@ -128,17 +117,6 @@ int interruptProcess(int pid)
/* Set the foreground window to the child. */
if (SetForegroundWindow (consoleHWND))
{
- /*
- if(0 != c_scan_code) {
- // Generate keystrokes as if user had typed Ctrl-C.
- keybd_event (VK_CONTROL, control_scan_code, 0, 0);
- keybd_event (vk_c_code, c_scan_code, 0, 0);
- keybd_event (vk_c_code, c_scan_code, KEYEVENTF_KEYUP, 0);
- keybd_event (VK_CONTROL, control_scan_code, KEYEVENTF_KEYUP, 0);
- }
- */
- /* Sleep for a bit to give time for respond */
- Sleep (100);
if(0 != break_scan_code) {
/* Generate keystrokes as if user had typed Ctrl-Break */
keybd_event (VK_CONTROL, control_scan_code, 0, 0);
diff --git a/core/org.eclipse.cdt.core.win32/library/spawner.c b/core/org.eclipse.cdt.core.win32/library/spawner.c
index 42217ae985a..b32679980b3 100644
--- a/core/org.eclipse.cdt.core.win32/library/spawner.c
+++ b/core/org.eclipse.cdt.core.win32/library/spawner.c
@@ -1,22 +1,26 @@
/**********************************************************************
- * Copyright (c) 2002,2003 QNX Software Systems and others.
+ * Copyright (c) 2002-2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
+ * are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
+ * http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ *
+ * spawner.c
+ *
+ * This is a part of JNI implementation of spawner
***********************************************************************/
-// spawner.cpp : Defines the entry point for the DLL application.
-//
#include "stdafx.h"
+#include "spawner.h"
CRITICAL_SECTION cs;
-TCHAR path[MAX_PATH + 1] = {_T('\0') };
+
+TCHAR path[MAX_PATH + 1] = {_T('\0') }; // Directory where spawner.dll is located
BOOL APIENTRY DllMain( HANDLE hModule,
@@ -48,4 +52,3 @@ BOOL APIENTRY DllMain( HANDLE hModule,
return TRUE;
}
-
diff --git a/core/org.eclipse.cdt.core.win32/library/starter/starter.cpp b/core/org.eclipse.cdt.core.win32/library/starter/starter.cpp
index 8b41e40a30c..7939182bf54 100644
--- a/core/org.eclipse.cdt.core.win32/library/starter/starter.cpp
+++ b/core/org.eclipse.cdt.core.win32/library/starter/starter.cpp
@@ -1,22 +1,19 @@
/**********************************************************************
- * Copyright (c) 2002,2003 QNX Software Systems and others.
+ * Copyright (c) 2002-2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
+ * are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
+ * http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
-***********************************************************************/
-/*
- * starter.c
+ *
+ * starter.cpp
*
* This is a small utility for windows spawner
- */
+***********************************************************************/
-//#define UNICODE
-//#define _UNICODE
#define STRICT
#include <Windows.h>
@@ -24,8 +21,9 @@
#include <tchar.h>
#include <stdio.h>
-// #define DEBUG_MONITOR
+//#define DEBUG_MONITOR
#define MAX_CMD_LINE_LENGTH (2049)
+#define PIPE_NAME_LENGTH 100
int copyTo(char * target, const char * source, int cpyLength, int availSpace);
@@ -58,8 +56,8 @@ BOOL WINAPI HandlerRoutine( DWORD dwCtrlType) // control signal type
extern "C" int _tmain(int argc, TCHAR* argv[]) {
- // Make sure that we've been passed the right number of arguments
- if (argc < 5) {
+ // Make sure that we've been passed the right number of arguments
+ if (argc < 7) {
_tprintf(__TEXT("Usage: %s (Three InheritableEventHandles) (CommandLineToSpawn)\n"),
argv[0]);
return(0);
@@ -69,7 +67,7 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
TCHAR szCmdLine[MAX_CMD_LINE_LENGTH] = { 0 };
int nPos = 0;
- for(int i = 4; i < argc; ++i)
+ for(int i = 6; i < argc; ++i)
{
int nCpyLen;
if(0 > (nCpyLen = copyTo(szCmdLine + nPos, argv[i], _tcslen(argv[i]), MAX_CMD_LINE_LENGTH - nPos)))
@@ -94,28 +92,81 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
#endif
BOOL exitProc = FALSE;
- HANDLE waitEvent = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[2]);
+ HANDLE waitEvent = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[4]);
HANDLE h[3];
- h[0] = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[1]);
- h[2] = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[3]); // This is a terminate event
+ h[0] = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[3]);
+ h[2] = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[5]); // This is a terminate event
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
+
+ int parentPid = strtol(argv[1], NULL, 10);
+ int nCounter = strtol(argv[2], NULL, 10);
+ char inPipeName[PIPE_NAME_LENGTH];
+ char outPipeName[PIPE_NAME_LENGTH];
+ char errPipeName[PIPE_NAME_LENGTH];
+
+ sprintf(inPipeName, "\\\\.\\pipe\\stdin%08i%010i", parentPid, nCounter);
+ sprintf(outPipeName, "\\\\.\\pipe\\stdout%08i%010i", parentPid, nCounter);
+ sprintf(errPipeName, "\\\\.\\pipe\\stderr%08i%010i", parentPid, nCounter);
#ifdef DEBUG_MONITOR
- sprintf(buffer, "starter start command: %s\n", szCmdLine);
+ sprintf(buffer, "Pipes: %s, %s, %s\n", inPipeName, outPipeName, errPipeName);
OutputDebugString(buffer);
#endif
+
+ HANDLE stdHandles[3];
+
+ SECURITY_ATTRIBUTES sa;
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.bInheritHandle = TRUE;
+ sa.lpSecurityDescriptor = NULL;
+
+ if((INVALID_HANDLE_VALUE == (stdHandles[0] = CreateFile(inPipeName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, &sa))) ||
+ (INVALID_HANDLE_VALUE == (stdHandles[1] = CreateFile(outPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa))) ||
+ (INVALID_HANDLE_VALUE == (stdHandles[2] = CreateFile(errPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa))))
+ {
+#ifdef DEBUG_MONITOR
+ sprintf(buffer, "Failed to open pipe %i, %i, %i: %i\n", stdHandles[0], stdHandles[1], stdHandles[2], GetLastError());
+ OutputDebugString(buffer);
+#endif
+ CloseHandle(stdHandles[0]);
+ CloseHandle(stdHandles[1]);
+ CloseHandle(stdHandles[2]);
+ return -1;;
+ }
+ SetHandleInformation(stdHandles[0], HANDLE_FLAG_INHERIT, TRUE);
+ SetHandleInformation(stdHandles[1], HANDLE_FLAG_INHERIT, TRUE);
+ SetHandleInformation(stdHandles[2], HANDLE_FLAG_INHERIT, TRUE);
+
+ if(!SetStdHandle(STD_INPUT_HANDLE, stdHandles[0]) ||
+ !SetStdHandle(STD_OUTPUT_HANDLE, stdHandles[1]) ||
+ !SetStdHandle(STD_ERROR_HANDLE, stdHandles[2])) {
+#ifdef DEBUG_MONITOR
+ sprintf(buffer, "Failed to reassign standard streams: %i\n", GetLastError());
+ OutputDebugString(buffer);
+#endif
+ CloseHandle(stdHandles[0]);
+ CloseHandle(stdHandles[1]);
+ CloseHandle(stdHandles[2]);
+ return -1;;
+ }
+
-// OutputDebugString(szCmdLine);
// Spawn the other processes as part of this Process Group
BOOL f = CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE,
0, NULL, NULL, &si, &pi);
-
+ // We don't need them any more
+ CloseHandle(stdHandles[0]);
+ CloseHandle(stdHandles[1]);
+ CloseHandle(stdHandles[2]);
if (f)
{
+#ifdef DEBUG_MONITOR
+ sprintf(buffer, "Process %i started\n", pi.dwProcessId);
+ OutputDebugString(buffer);
+#endif
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
@@ -151,6 +202,7 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
break;
default:
// Unexpected code
+#ifdef DEBUG_MONITOR
LPTSTR lpMsgBuf;
FormatMessage(
@@ -167,6 +219,7 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
OutputDebugString(lpMsgBuf);
// Free the buffer.
LocalFree( lpMsgBuf );
+#endif
exitProc = TRUE;
break;
}
@@ -177,12 +230,21 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
CloseHandle(waitEvent);
CloseHandle(h[0]);
+ CloseHandle(h[1]);
CloseHandle(h[2]);
return(dwExitCode);
}
-// Return number of bytes in target or -1 in case of error
+/////////////////////////////////////////////////////////////////////////////////////
+// Use this utility program to process correctly quotation marks in the command line
+// Arguments:
+// target - string to copy to
+// source - string to copy from
+// cpyLength - copy length
+// availSpace - size of the target buffer
+// Return :number of bytes used in target, or -1 in case of error
+/////////////////////////////////////////////////////////////////////////////////////
int copyTo(LPTSTR target, LPCTSTR source, int cpyLength, int availSpace)
{
BOOL bSlash = FALSE;

Back to the top