mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-05 07:15:39 +02:00
Update the starter/spawner to use named pipes.
Patch from alex.
This commit is contained in:
parent
385ac1b870
commit
c2ba759a8c
13 changed files with 482 additions and 203 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2004-02-12 Alex Chapiro
|
||||||
|
|
||||||
|
Update starter and spawner to use named pipes.
|
||||||
|
Update the binaries.
|
||||||
|
|
||||||
2003-08-29 Alex Chapiro
|
2003-08-29 Alex Chapiro
|
||||||
|
|
||||||
This patch just increase command line buffer up to OS limit (2K). It also
|
This patch just increase command line buffer up to OS limit (2K). It also
|
||||||
|
|
|
@ -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 */
|
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
/* Header for class org_eclipse_cdt_utils_spawner_Spawner */
|
/* 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
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor
|
||||||
(JNIEnv *, jobject, jint);
|
(JNIEnv *, jobject, jint);
|
||||||
|
|
||||||
|
// #define DEBUG_MONITOR
|
||||||
|
|
||||||
int interruptProcess(int pid);
|
int interruptProcess(int pid);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// #define DEBUG_MONITOR
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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 */
|
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
/* Header for class com_qnx_tools_utils_spawner_SpawnerInputStream */
|
/* Header for class com_qnx_tools_utils_spawner_SpawnerInputStream */
|
||||||
|
|
|
@ -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 */
|
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
/* Header for class com_qnx_tools_utils_spawner_SpawnerOutputStream */
|
/* Header for class com_qnx_tools_utils_spawner_SpawnerOutputStream */
|
||||||
|
|
|
@ -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
|
* 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
|
* 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:
|
* Contributors:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* 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
|
// stdafx.cpp : source file that includes just the standard includes
|
||||||
// spawner.pch will be the pre-compiled header
|
// spawner.pch will be the pre-compiled header
|
||||||
|
|
|
@ -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
|
* 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
|
* 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:
|
* Contributors:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* 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,
|
// stdafx.h : include file for standard system include files,
|
||||||
// or project specific include files that are used frequently, but
|
// or project specific include files that are used frequently, but
|
||||||
// are changed infrequently
|
// are changed infrequently
|
||||||
|
|
|
@ -1,18 +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
|
* 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
|
* 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:
|
* Contributors:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* QNX Software Systems - Initial API and implementation
|
||||||
***********************************************************************/
|
*
|
||||||
/*
|
|
||||||
* Win32ProcessEx.c
|
* Win32ProcessEx.c
|
||||||
*
|
*
|
||||||
* This is a JNI implementation of spawner
|
* This is a JNI implementation of spawner
|
||||||
*/
|
***********************************************************************/
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -23,37 +23,54 @@
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
||||||
// #define DEBUG_MONITOR
|
|
||||||
|
|
||||||
#define PIPE_SIZE 512
|
#define PIPE_SIZE 512 // Size of pipe buffer
|
||||||
#define MAX_CMD_SIZE 2049
|
#define MAX_CMD_SIZE 2049 // Maximum size of command line
|
||||||
#define MAX_ENV_SIZE 4096
|
#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.
|
||||||
|
|
||||||
#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 void * (JNICALL * JVM_GetThreadInterruptEvent)();
|
||||||
typedef JNIEXPORT char * (JNICALL * JVM_NativePath)(const char *);
|
typedef JNIEXPORT char * (JNICALL * JVM_NativePath)(const char *);
|
||||||
|
|
||||||
|
// Process description block. Should be created for each launched process
|
||||||
typedef struct _procInfo {
|
typedef struct _procInfo {
|
||||||
int pid; // Process ID
|
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 eventBreak;
|
||||||
HANDLE eventWait;
|
HANDLE eventWait;
|
||||||
HANDLE eventTerminate;
|
HANDLE eventTerminate;
|
||||||
} procInfo_t, * pProcInfo_t;
|
} 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);
|
JNIEXPORT void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg);
|
||||||
|
|
||||||
|
// Creates _procInfo block for every launched procss
|
||||||
pProcInfo_t createProcInfo();
|
pProcInfo_t createProcInfo();
|
||||||
|
|
||||||
|
// Find process description for this pid
|
||||||
pProcInfo_t findProcInfo(int pid);
|
pProcInfo_t findProcInfo(int pid);
|
||||||
|
|
||||||
|
// We launch separate thread for each project to trap it termination
|
||||||
unsigned int _stdcall waitProcTermination(void* pv) ;
|
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 int copyTo(char * target, const char * source, int cpyLenght, int availSpace);
|
||||||
|
|
||||||
|
// Use this function to clean project descriptor and return it to the pool of available blocks.
|
||||||
static void cleanUpProcBlock(pProcInfo_t pCurProcInfo);
|
static void cleanUpProcBlock(pProcInfo_t pCurProcInfo);
|
||||||
|
|
||||||
|
|
||||||
|
// Signal codes
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SIG_NOOP,
|
SIG_NOOP,
|
||||||
SIG_HUP,
|
SIG_HUP,
|
||||||
|
@ -65,20 +82,27 @@ typedef enum {
|
||||||
extern CRITICAL_SECTION cs;
|
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 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
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
||||||
(JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir, jintArray channels)
|
(JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir, jintArray channels)
|
||||||
{
|
{
|
||||||
|
HANDLE stdHandles[3];
|
||||||
HANDLE hread[3], hwrite[3];
|
|
||||||
SECURITY_ATTRIBUTES sa;
|
|
||||||
PROCESS_INFORMATION pi = {0};
|
PROCESS_INFORMATION pi = {0};
|
||||||
STARTUPINFO si;
|
STARTUPINFO si;
|
||||||
DWORD flags = 0;
|
DWORD flags = 0;
|
||||||
|
@ -91,6 +115,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
||||||
jsize nCmdTokens = 0;
|
jsize nCmdTokens = 0;
|
||||||
jsize nEnvVars = 0;
|
jsize nEnvVars = 0;
|
||||||
int i;
|
int i;
|
||||||
|
DWORD pid = GetCurrentProcessId();
|
||||||
int nPos;
|
int nPos;
|
||||||
pProcInfo_t pCurProcInfo;
|
pProcInfo_t pCurProcInfo;
|
||||||
DWORD dwThreadId;
|
DWORD dwThreadId;
|
||||||
|
@ -100,6 +125,10 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
||||||
#ifdef DEBUG_MONITOR
|
#ifdef DEBUG_MONITOR
|
||||||
char buffer[1000];
|
char buffer[1000];
|
||||||
#endif
|
#endif
|
||||||
|
int nLocalCounter;
|
||||||
|
char inPipeName[PIPE_NAME_LENGTH];
|
||||||
|
char outPipeName[PIPE_NAME_LENGTH];
|
||||||
|
char errPipeName[PIPE_NAME_LENGTH];
|
||||||
|
|
||||||
if((HIBYTE(LOWORD(GetVersion()))) & 0x80)
|
if((HIBYTE(LOWORD(GetVersion()))) & 0x80)
|
||||||
{
|
{
|
||||||
|
@ -113,25 +142,39 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sa.nLength = sizeof(sa);
|
ZeroMemory(stdHandles, sizeof(stdHandles));
|
||||||
sa.lpSecurityDescriptor = 0;
|
|
||||||
sa.bInheritHandle = TRUE;
|
|
||||||
|
|
||||||
memset(hread, 0, sizeof(hread));
|
// Create pipe names
|
||||||
memset(hwrite, 0, sizeof(hwrite));
|
EnterCriticalSection(&cs);
|
||||||
if (!(CreatePipe(&hread[0], &hwrite[0], &sa, PIPE_SIZE) &&
|
sprintf(inPipeName, "\\\\.\\pipe\\stdin%08i%010i", pid, nCounter);
|
||||||
CreatePipe(&hread[1], &hwrite[1], &sa, PIPE_SIZE) &&
|
sprintf(outPipeName, "\\\\.\\pipe\\stdout%08i%010i", pid, nCounter);
|
||||||
CreatePipe(&hread[2], &hwrite[2], &sa, PIPE_SIZE)))
|
sprintf(errPipeName, "\\\\.\\pipe\\stderr%08i%010i", pid, nCounter);
|
||||||
{
|
nLocalCounter = nCounter;
|
||||||
CloseHandle(hread[0]);
|
++nCounter;
|
||||||
CloseHandle(hread[1]);
|
LeaveCriticalSection(&cs);
|
||||||
CloseHandle(hread[2]);
|
|
||||||
CloseHandle(hwrite[0]);
|
|
||||||
CloseHandle(hwrite[1]);
|
if ((INVALID_HANDLE_VALUE == (stdHandles[0] = CreateNamedPipe(inPipeName, PIPE_ACCESS_OUTBOUND,
|
||||||
CloseHandle(hwrite[2]);
|
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");
|
ThrowByName(env, "java/io/IOException", "CreatePipe");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_MONITOR
|
||||||
|
sprintf(buffer, "Opened pipes: %s, %s, %s\n", inPipeName, outPipeName, errPipeName);
|
||||||
|
OutputDebugString(buffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
nCmdTokens = (*env) -> GetArrayLength(env, cmdarray);
|
nCmdTokens = (*env) -> GetArrayLength(env, cmdarray);
|
||||||
nEnvVars = (*env) -> GetArrayLength(env, envp);
|
nEnvVars = (*env) -> GetArrayLength(env, envp);
|
||||||
|
@ -144,17 +187,18 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Construct starter's command line
|
||||||
sprintf(eventBreakName, "SABreak%p", pCurProcInfo);
|
sprintf(eventBreakName, "SABreak%p", pCurProcInfo);
|
||||||
sprintf(eventWaitName, "SAWait%p", pCurProcInfo);
|
sprintf(eventWaitName, "SAWait%p", pCurProcInfo);
|
||||||
sprintf(eventTerminateName, "SATerm%p", pCurProcInfo);
|
sprintf(eventTerminateName, "SATerm%p", pCurProcInfo);
|
||||||
pCurProcInfo -> eventBreak = CreateEvent(NULL, TRUE, FALSE, eventBreakName);
|
pCurProcInfo -> eventBreak = CreateEvent(NULL, TRUE, FALSE, eventBreakName);
|
||||||
ResetEvent(pCurProcInfo -> eventBreak);
|
ResetEvent(pCurProcInfo -> eventBreak);
|
||||||
pCurProcInfo -> eventWait = CreateEvent(NULL, TRUE, FALSE, eventWaitName);
|
pCurProcInfo -> eventWait = CreateEvent(NULL, TRUE, FALSE, eventWaitName);
|
||||||
|
ResetEvent(pCurProcInfo -> eventWait);
|
||||||
pCurProcInfo -> eventTerminate = CreateEvent(NULL, TRUE, FALSE, eventTerminateName);
|
pCurProcInfo -> eventTerminate = CreateEvent(NULL, TRUE, FALSE, eventTerminateName);
|
||||||
ResetEvent(pCurProcInfo -> eventTerminate);
|
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
|
// Prepare command line
|
||||||
for(i = 0; i < nCmdTokens; ++i)
|
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.cb = sizeof(si);
|
||||||
si.dwFlags |= STARTF_USESTDHANDLES;
|
|
||||||
si.dwFlags |= STARTF_USESHOWWINDOW;
|
si.dwFlags |= STARTF_USESHOWWINDOW;
|
||||||
si.wShowWindow = SW_HIDE; // Processes in the Process Group are hidden
|
si.wShowWindow = SW_HIDE; // Processes in the Process Group are hidden
|
||||||
si.hStdInput = hread[0];
|
|
||||||
si.hStdOutput = hwrite[1];
|
|
||||||
si.hStdError = hwrite[2];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SetHandleInformation(stdHandles[0], HANDLE_FLAG_INHERIT, FALSE);
|
||||||
SetHandleInformation(hwrite[0], HANDLE_FLAG_INHERIT, FALSE);
|
SetHandleInformation(stdHandles[1], HANDLE_FLAG_INHERIT, FALSE);
|
||||||
SetHandleInformation(hread[1], HANDLE_FLAG_INHERIT, FALSE);
|
SetHandleInformation(stdHandles[2], HANDLE_FLAG_INHERIT, FALSE);
|
||||||
SetHandleInformation(hread[2], HANDLE_FLAG_INHERIT, FALSE);
|
|
||||||
|
|
||||||
flags = CREATE_NEW_CONSOLE;
|
flags = CREATE_NEW_CONSOLE;
|
||||||
flags |= CREATE_NO_WINDOW;
|
flags |= CREATE_NO_WINDOW;
|
||||||
|
@ -251,14 +290,15 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
||||||
#ifdef DEBUG_MONITOR
|
#ifdef DEBUG_MONITOR
|
||||||
OutputDebugString(szCmdLine);
|
OutputDebugString(szCmdLine);
|
||||||
#endif
|
#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 */
|
ret = CreateProcess(0, /* executable name */
|
||||||
szCmdLine, /* command line */
|
szCmdLine, /* command line */
|
||||||
0, /* process security attribute */
|
0, /* process security attribute */
|
||||||
0, /* thread security attribute */
|
0, /* thread security attribute */
|
||||||
TRUE, /* inherits system handles */
|
FALSE, /* inherits system handles */
|
||||||
flags, /* normal attached process */
|
flags, /* normal attached process */
|
||||||
envBlk, /* environment block */
|
envBlk, /* environment block */
|
||||||
cwd, /* change to the new current directory */
|
cwd, /* change to the new current directory */
|
||||||
&si, /* (in) startup information */
|
&si, /* (in) startup information */
|
||||||
&pi); /* (out) process information */
|
&pi); /* (out) process information */
|
||||||
|
@ -270,18 +310,13 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
||||||
|
|
||||||
free(szEnvBlock);
|
free(szEnvBlock);
|
||||||
|
|
||||||
CloseHandle(hread[0]);
|
if (!ret) // Launching error
|
||||||
CloseHandle(hwrite[1]);
|
|
||||||
CloseHandle(hwrite[2]);
|
|
||||||
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
{
|
{
|
||||||
LPTSTR lpMsgBuf;
|
LPTSTR lpMsgBuf;
|
||||||
|
|
||||||
CloseHandle(hwrite[0]);
|
CloseHandle(stdHandles[0]);
|
||||||
CloseHandle(hread[1]);
|
CloseHandle(stdHandles[1]);
|
||||||
CloseHandle(hread[2]);
|
CloseHandle(stdHandles[2]);
|
||||||
FormatMessage(
|
FormatMessage(
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
@ -327,18 +362,19 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_MONITOR
|
|
||||||
sprintf(buffer, "Process %i created\n", pi.dwProcessId);
|
|
||||||
OutputDebugString(buffer);
|
|
||||||
#endif
|
|
||||||
ret = (long)(pCurProcInfo -> uid);
|
ret = (long)(pCurProcInfo -> uid);
|
||||||
file_handles[0] = (int)hwrite[0];
|
|
||||||
file_handles[1] = (int)hread[1];
|
// Prepare stream handlers to return to java program
|
||||||
file_handles[2] = (int)hread[2];
|
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);
|
(*env) -> SetIntArrayRegion(env, channels, 0, 3, file_handles);
|
||||||
}
|
}
|
||||||
CloseHandle(h[1]);
|
CloseHandle(h[1]);
|
||||||
LeaveCriticalSection(&cs);
|
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
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
|
||||||
(JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir)
|
(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)))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
nPos += nCpyLen;
|
nPos += nCpyLen;
|
||||||
|
@ -418,7 +461,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
|
||||||
szEnvBlock = (char *)realloc(szEnvBlock, nBlkSize);
|
szEnvBlock = (char *)realloc(szEnvBlock, nBlkSize);
|
||||||
if(NULL == szEnvBlock)
|
if(NULL == szEnvBlock)
|
||||||
{
|
{
|
||||||
ThrowByName(env, "java/io/IOException", "Not enough memory");
|
ThrowByName(env, "java/io/Exception", "Not enough memory");
|
||||||
return 0;
|
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);
|
si.cb = sizeof(si);
|
||||||
|
|
||||||
|
|
||||||
|
@ -472,7 +515,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
|
||||||
free(cwd);
|
free(cwd);
|
||||||
free(szEnvBlock);
|
free(szEnvBlock);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret) // error
|
||||||
{
|
{
|
||||||
LPTSTR lpMsgBuf;
|
LPTSTR lpMsgBuf;
|
||||||
|
|
||||||
|
@ -494,6 +537,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Clean-up
|
||||||
CloseHandle(pi.hThread);
|
CloseHandle(pi.hThread);
|
||||||
CloseHandle(pi.hProcess);
|
CloseHandle(pi.hProcess);
|
||||||
ret = (long)pi.dwProcessId; //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
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise
|
||||||
(JNIEnv * env, jobject process, jint uid, jint signal)
|
(JNIEnv * env, jobject process, jint uid, jint signal)
|
||||||
{
|
{
|
||||||
|
@ -572,6 +622,11 @@ 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
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor
|
||||||
(JNIEnv * env, jobject process, jint uid)
|
(JNIEnv * env, jobject process, jint uid)
|
||||||
{
|
{
|
||||||
|
@ -609,6 +664,12 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor
|
||||||
|
|
||||||
// Utilities
|
// 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
|
JNIEXPORT void JNICALL
|
||||||
ThrowByName(JNIEnv *env, const char *name, const char *msg)
|
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()
|
pProcInfo_t createProcInfo()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -634,7 +700,7 @@ pProcInfo_t createProcInfo()
|
||||||
if(NULL == pInfo)
|
if(NULL == pInfo)
|
||||||
{
|
{
|
||||||
pInfo = malloc(sizeof(procInfo_t) * MAX_PROCS);
|
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)
|
for(i = 0; i < MAX_PROCS; ++i)
|
||||||
|
@ -653,6 +719,11 @@ pProcInfo_t createProcInfo()
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Using unique process ID finds process descriptor
|
||||||
|
// Arguments: no
|
||||||
|
// Return : pointer to the process descriptor
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
pProcInfo_t findProcInfo(int uid)
|
pProcInfo_t findProcInfo(int uid)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -672,6 +743,11 @@ pProcInfo_t findProcInfo(int uid)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Cleans up vacant process descriptor
|
||||||
|
// Arguments:
|
||||||
|
// pCurProcInfo - pointer to descriptor to clean up
|
||||||
|
// Return : no
|
||||||
void cleanUpProcBlock(pProcInfo_t pCurProcInfo)
|
void cleanUpProcBlock(pProcInfo_t pCurProcInfo)
|
||||||
{
|
{
|
||||||
if(0 != pCurProcInfo -> eventBreak)
|
if(0 != pCurProcInfo -> eventBreak)
|
||||||
|
@ -693,11 +769,16 @@ void cleanUpProcBlock(pProcInfo_t pCurProcInfo)
|
||||||
pCurProcInfo -> pid = 0;
|
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)
|
unsigned int _stdcall waitProcTermination(void* pv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int pid = (int)pv;
|
int pid = (int)pv;
|
||||||
DWORD rc = 0;
|
|
||||||
#ifdef DEBUG_MONITOR
|
#ifdef DEBUG_MONITOR
|
||||||
char buffer[1000];
|
char buffer[1000];
|
||||||
#endif
|
#endif
|
||||||
|
@ -742,7 +823,15 @@ unsigned int _stdcall waitProcTermination(void* pv)
|
||||||
return 0;
|
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)
|
int copyTo(char * target, const char * source, int cpyLength, int availSpace)
|
||||||
{
|
{
|
||||||
BOOL bSlash = FALSE;
|
BOOL bSlash = FALSE;
|
||||||
|
|
|
@ -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
|
* 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
|
* 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:
|
* Contributors:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* 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 "stdafx.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "spawner.h"
|
||||||
#include "SpawnerInputStream.h"
|
#include "SpawnerInputStream.h"
|
||||||
#include "SpawnerOutputStream.h"
|
#include "SpawnerOutputStream.h"
|
||||||
|
|
||||||
|
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
||||||
|
@ -37,35 +39,87 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
|
||||||
{
|
{
|
||||||
BYTE tmpBuf[BUFF_SIZE];
|
BYTE tmpBuf[BUFF_SIZE];
|
||||||
int nBuffOffset = 0;
|
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)
|
while(len > nBuffOffset)
|
||||||
{
|
{
|
||||||
int nNumberOfBytesToRead = min(len - nBuffOffset, BUFF_SIZE);
|
int nNumberOfBytesToRead = min(len - nBuffOffset, BUFF_SIZE);
|
||||||
int nNumberOfBytesRead;
|
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();
|
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
|
if(err == ERROR_BROKEN_PIPE) // Pipe was closed
|
||||||
return 0;
|
break;
|
||||||
if(err != ERROR_MORE_DATA) // Otherwise error means just that there are more data
|
if(err != 0)
|
||||||
{ // than buffer can accept
|
{
|
||||||
FormatMessage(
|
LPTSTR lpMsgBuf;
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
#ifdef DEBUG_MONITOR
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
char buffer[200];
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
sprintf(buffer, "Read failed - %i, error %i\n", fd, err);
|
||||||
NULL,
|
OutputDebugString(buffer);
|
||||||
err,
|
#endif
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
if(err != ERROR_MORE_DATA) // Otherwise error means just that there are more data
|
||||||
(LPTSTR) &lpMsgBuf,
|
{ // than buffer can accept
|
||||||
0,
|
FormatMessage(
|
||||||
NULL
|
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);
|
ThrowByName(env, "java/io/IOException", lpMsgBuf);
|
||||||
LocalFree( lpMsgBuf );
|
LocalFree( lpMsgBuf );
|
||||||
return 0;
|
nBuffOffset = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(nNumberOfBytesRead > 0)
|
if(nNumberOfBytesRead > 0)
|
||||||
|
@ -76,6 +130,11 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
|
||||||
if(nNumberOfBytesRead != nNumberOfBytesToRead)
|
if(nNumberOfBytesRead != nNumberOfBytesToRead)
|
||||||
break;
|
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
|
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
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0
|
||||||
(JNIEnv * env, jobject proc, jint fd)
|
(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];
|
BYTE tmpBuf[BUFF_SIZE];
|
||||||
int nBuffOffset = 0;
|
int nBuffOffset = 0;
|
||||||
|
|
||||||
|
|
||||||
while(len > nBuffOffset)
|
while(len > nBuffOffset)
|
||||||
{
|
{
|
||||||
int nNumberOfBytesToWrite = min(len - nBuffOffset, BUFF_SIZE);
|
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
|
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0
|
||||||
(JNIEnv * env, jobject proc, jint fd)
|
(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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* 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
|
* 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:
|
* Contributors:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* 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 "stdafx.h"
|
||||||
#include "Spawner.h"
|
#include "Spawner.h"
|
||||||
|
|
||||||
|
@ -19,10 +20,17 @@
|
||||||
|
|
||||||
extern void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg);
|
extern void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg);
|
||||||
|
|
||||||
// #define DEBUG_MONITOR
|
|
||||||
|
|
||||||
static HWND consoleHWND;
|
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
|
static BOOL CALLBACK
|
||||||
find_child_console (HWND hwnd, LPARAM arg)
|
find_child_console (HWND hwnd, LPARAM arg)
|
||||||
{
|
{
|
||||||
|
@ -46,35 +54,13 @@ find_child_console (HWND hwnd, LPARAM arg)
|
||||||
return TRUE;
|
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)
|
int interruptProcess(int pid)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_MONITOR
|
#ifdef DEBUG_MONITOR
|
||||||
|
@ -89,10 +75,13 @@ int interruptProcess(int pid)
|
||||||
sprintf(buffer, "Try to interrupt process %i\n", pid);
|
sprintf(buffer, "Try to interrupt process %i\n", pid);
|
||||||
OutputDebugString(buffer);
|
OutputDebugString(buffer);
|
||||||
#endif
|
#endif
|
||||||
|
// Find console
|
||||||
EnumWindows (find_child_console, (LPARAM) pid);
|
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);
|
BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0);
|
||||||
/* Fake Ctrl-C for SIGINT, and Ctrl-Break for SIGQUIT. */
|
/* Fake Ctrl-C for SIGINT, and Ctrl-Break for SIGQUIT. */
|
||||||
BYTE vk_c_code = 'C';
|
BYTE vk_c_code = 'C';
|
||||||
|
@ -128,17 +117,6 @@ int interruptProcess(int pid)
|
||||||
/* Set the foreground window to the child. */
|
/* Set the foreground window to the child. */
|
||||||
if (SetForegroundWindow (consoleHWND))
|
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) {
|
if(0 != break_scan_code) {
|
||||||
/* Generate keystrokes as if user had typed Ctrl-Break */
|
/* Generate keystrokes as if user had typed Ctrl-Break */
|
||||||
keybd_event (VK_CONTROL, control_scan_code, 0, 0);
|
keybd_event (VK_CONTROL, control_scan_code, 0, 0);
|
||||||
|
|
|
@ -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
|
* 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
|
* 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:
|
* Contributors:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* 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 "stdafx.h"
|
||||||
|
#include "spawner.h"
|
||||||
|
|
||||||
|
|
||||||
CRITICAL_SECTION cs;
|
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,
|
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||||
|
@ -48,4 +52,3 @@ BOOL APIENTRY DllMain( HANDLE hModule,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
* 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
|
* 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:
|
* Contributors:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* QNX Software Systems - Initial API and implementation
|
||||||
***********************************************************************/
|
*
|
||||||
/*
|
* starter.cpp
|
||||||
* starter.c
|
|
||||||
*
|
*
|
||||||
* This is a small utility for windows spawner
|
* This is a small utility for windows spawner
|
||||||
*/
|
***********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
//#define UNICODE
|
|
||||||
//#define _UNICODE
|
|
||||||
|
|
||||||
#define STRICT
|
#define STRICT
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
@ -24,8 +21,9 @@
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
// #define DEBUG_MONITOR
|
//#define DEBUG_MONITOR
|
||||||
#define MAX_CMD_LINE_LENGTH (2049)
|
#define MAX_CMD_LINE_LENGTH (2049)
|
||||||
|
#define PIPE_NAME_LENGTH 100
|
||||||
|
|
||||||
int copyTo(char * target, const char * source, int cpyLength, int availSpace);
|
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[]) {
|
extern "C" int _tmain(int argc, TCHAR* argv[]) {
|
||||||
|
|
||||||
// Make sure that we've been passed the right number of arguments
|
// Make sure that we've been passed the right number of arguments
|
||||||
if (argc < 5) {
|
if (argc < 7) {
|
||||||
_tprintf(__TEXT("Usage: %s (Three InheritableEventHandles) (CommandLineToSpawn)\n"),
|
_tprintf(__TEXT("Usage: %s (Three InheritableEventHandles) (CommandLineToSpawn)\n"),
|
||||||
argv[0]);
|
argv[0]);
|
||||||
return(0);
|
return(0);
|
||||||
|
@ -69,7 +67,7 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
|
||||||
TCHAR szCmdLine[MAX_CMD_LINE_LENGTH] = { 0 };
|
TCHAR szCmdLine[MAX_CMD_LINE_LENGTH] = { 0 };
|
||||||
int nPos = 0;
|
int nPos = 0;
|
||||||
|
|
||||||
for(int i = 4; i < argc; ++i)
|
for(int i = 6; i < argc; ++i)
|
||||||
{
|
{
|
||||||
int nCpyLen;
|
int nCpyLen;
|
||||||
if(0 > (nCpyLen = copyTo(szCmdLine + nPos, argv[i], _tcslen(argv[i]), MAX_CMD_LINE_LENGTH - nPos)))
|
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
|
#endif
|
||||||
|
|
||||||
BOOL exitProc = FALSE;
|
BOOL exitProc = FALSE;
|
||||||
HANDLE waitEvent = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[2]);
|
HANDLE waitEvent = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[4]);
|
||||||
HANDLE h[3];
|
HANDLE h[3];
|
||||||
h[0] = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[1]);
|
h[0] = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[3]);
|
||||||
h[2] = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[3]); // This is a terminate event
|
h[2] = OpenEvent(EVENT_ALL_ACCESS, TRUE, argv[5]); // This is a terminate event
|
||||||
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
|
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
|
#ifdef DEBUG_MONITOR
|
||||||
sprintf(buffer, "starter start command: %s\n", szCmdLine);
|
sprintf(buffer, "Pipes: %s, %s, %s\n", inPipeName, outPipeName, errPipeName);
|
||||||
OutputDebugString(buffer);
|
OutputDebugString(buffer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// OutputDebugString(szCmdLine);
|
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;;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Spawn the other processes as part of this Process Group
|
// Spawn the other processes as part of this Process Group
|
||||||
BOOL f = CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE,
|
BOOL f = CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE,
|
||||||
0, NULL, NULL, &si, &pi);
|
0, NULL, NULL, &si, &pi);
|
||||||
|
// We don't need them any more
|
||||||
|
CloseHandle(stdHandles[0]);
|
||||||
|
CloseHandle(stdHandles[1]);
|
||||||
|
CloseHandle(stdHandles[2]);
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_MONITOR
|
||||||
|
sprintf(buffer, "Process %i started\n", pi.dwProcessId);
|
||||||
|
OutputDebugString(buffer);
|
||||||
|
#endif
|
||||||
SetEvent(waitEvent); // Means thar process has been spawned
|
SetEvent(waitEvent); // Means thar process has been spawned
|
||||||
CloseHandle(pi.hThread);
|
CloseHandle(pi.hThread);
|
||||||
h[1] = pi.hProcess;
|
h[1] = pi.hProcess;
|
||||||
|
|
||||||
while(!exitProc)
|
while(!exitProc)
|
||||||
{
|
{
|
||||||
// Wait for the spawned-process to die or for the event
|
// Wait for the spawned-process to die or for the event
|
||||||
|
@ -151,6 +202,7 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Unexpected code
|
// Unexpected code
|
||||||
|
#ifdef DEBUG_MONITOR
|
||||||
LPTSTR lpMsgBuf;
|
LPTSTR lpMsgBuf;
|
||||||
|
|
||||||
FormatMessage(
|
FormatMessage(
|
||||||
|
@ -167,6 +219,7 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
|
||||||
OutputDebugString(lpMsgBuf);
|
OutputDebugString(lpMsgBuf);
|
||||||
// Free the buffer.
|
// Free the buffer.
|
||||||
LocalFree( lpMsgBuf );
|
LocalFree( lpMsgBuf );
|
||||||
|
#endif
|
||||||
exitProc = TRUE;
|
exitProc = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -177,12 +230,21 @@ extern "C" int _tmain(int argc, TCHAR* argv[]) {
|
||||||
|
|
||||||
CloseHandle(waitEvent);
|
CloseHandle(waitEvent);
|
||||||
CloseHandle(h[0]);
|
CloseHandle(h[0]);
|
||||||
|
CloseHandle(h[1]);
|
||||||
CloseHandle(h[2]);
|
CloseHandle(h[2]);
|
||||||
|
|
||||||
return(dwExitCode);
|
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)
|
int copyTo(LPTSTR target, LPCTSTR source, int cpyLength, int availSpace)
|
||||||
{
|
{
|
||||||
BOOL bSlash = FALSE;
|
BOOL bSlash = FALSE;
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Add table
Reference in a new issue