From c2ba759a8cb1be0f2888ada5e71828b60926388b Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Thu, 12 Feb 2004 21:12:51 +0000 Subject: [PATCH] Update the starter/spawner to use named pipes. Patch from alex. --- core/org.eclipse.cdt.core.win32/ChangeLog | 5 + .../library/Spawner.h | 20 ++ .../library/SpawnerInputStream.h | 15 + .../library/SpawnerOutputStream.h | 14 + .../library/StdAfx.c | 10 +- .../library/StdAfx.h | 11 +- .../library/Win32ProcessEx.c | 275 ++++++++++++------ .../library/iostream.c | 140 +++++++-- .../library/raise.c | 74 ++--- .../library/spawner.c | 17 +- .../library/starter/starter.cpp | 104 +++++-- .../os/win32/x86/spawner.dll | Bin 61440 -> 61440 bytes .../os/win32/x86/starter.exe | Bin 16384 -> 16384 bytes 13 files changed, 482 insertions(+), 203 deletions(-) diff --git a/core/org.eclipse.cdt.core.win32/ChangeLog b/core/org.eclipse.cdt.core.win32/ChangeLog index fffce6ca5d4..8ab4304bdc3 100644 --- a/core/org.eclipse.cdt.core.win32/ChangeLog +++ b/core/org.eclipse.cdt.core.win32/ChangeLog @@ -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 This patch just increase command line buffer up to OS limit (2K). It also 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 /* 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 /* 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 /* 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 #include #include #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); + +// 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; + ZeroMemory(stdHandles, sizeof(stdHandles)); - 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]); + // 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 #include +#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 - ); + 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 ); - return 0; + 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 @@ -24,8 +21,9 @@ #include #include -// #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; diff --git a/core/org.eclipse.cdt.core.win32/os/win32/x86/spawner.dll b/core/org.eclipse.cdt.core.win32/os/win32/x86/spawner.dll index 771fd664dad8b76c8c3fa72fd43caeac80df5e96..07fa17c03edf4ff6b3cced12fe8ba305eea0243c 100644 GIT binary patch delta 13751 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 IEiIA%U#fXAR{#J2 delta 13311 zcmd^ldwf$>*7ix7(g0~2pwR#=4G^G0!INuqIk^BW7A=t8(pCx-Z83z31rjVyC9P>k z!Xa2ZsHlumiw+~apVgvPhryP1xQvK+14dA)qHnOMMHnbrIq$PiT0!5L-}le=-CK{_eM^`{z1Iw3hjRr?SJNP7D|JQ-QO&< zAKU*E%8&D(+}|qj*YEE^+48_+LVIpyoxq>B{9X^ywPn0g=E|a|9Fc^&Z{>W)mJ7+^ z*VDOSqWMEz&r#GmF-0YFOGOjK<#Ak{SQpz!QQ4v`Es01OV*Lui5)Vx=n4xNEb?7=0A7cH#oBGw#8qP!IJW0+hIg$|dO z@=$kThVzRLflh+D9fpdyZP33+>#pk*a|FP^|KEN{;CfpB1@0 zWuquLuTXEH?c9l@W#_v{UsYL!rn;ZLBR#4Gfmv!@zPhf3AS ziS<7bw@*(OWb*k>SX(meVtYeAwVFR^?e)pMA~%2172p*Nc;If?p-i=!n8AXDjVEKn zTab)|D%EnxM2JiwWPT$eSk8ijRS*#@pHtB1TjVY06-o@c5!ThW`|NC~TFDwrf<;~` zKRS_sR|MhYLNBI)X~hgy!~z{6$$~l1Kd3H$V1z3^nU^9{7%=BM(!OC{blrko@&gj8 zao`iYphB#vi`W`UWbS0rgg{h81!@~4C=w6kQ+J_PN>RG@{K8PCI@?{O`wnG+hpaU` z>O!Lwr3z5P^-j_siBnKiuuB4(l2_zFqwdJYqgOg=eUq_QBtv13{#95;A~i44GmN4z z&43V}WUK>9iruG{fzA4he=@e2AfY4@eUNZP-i}J#ETB80`!JM)6*pvKxKM$bMk@`a z9%VY*Rf@XFLm@3-1LW~>jxHS(F%c0O`&yvp z|BlKKs(z4a0F~V*Z`_d&!9Tcl2V9dMu2OwTF77xS<`^TV6edr8+(bmc}YLf2OH9@5p0uDr+; zbg{O~M&zL`HM~*dDik&WJKc#sS7^4B4}1bGJ0X&b02X;E{$zM7LIpO?mgNn0fm6gqQ+RMj~z(26jbW8Hs`W5P50AE+ssi1V#$}-MkSc@>LR+m#j3K z5I`Q}x9p92>Qp}JJ4pQ&>@hdo>%GyJVOvcn(Su;VxGp=KAJ-*&UR`k@GMKUcrh?WfPFK;0|Gp`WkqjvM6%wK3I86G!G;ffhw5w)(GO^_V7M+ z8!DKs>C$c}Iu{@eUg_lc`pFDKsue8~VEUL|7NE$aSb*-G#nPAhbu_ zONvcuimVw@3<~}v30i2Ra|f!}p?QevOm$9pQ*`hevt1GC#5yBYQk8zebN8ru7)0G7Ym#$J}Xlg#_ug3K_N% znte!kO2kL5HwJ2b>=3AR^Nl&ti%#YZJJT`FlJeh8NJ!?ywYmHW;%8)D43X|aA*?Cs z#CnoW6FNPmgNCu2gp86Kd0uiOx(D3UDo?&364Nc*^^_D+q>S4lGI6hro1P%tcM3fN zi@<$5Zp_$$dsFZ*kBd_^Ihc}2JkqQ|&ZVY0MDw{NsR~gk=TA)ycv5lRs>1~+kg#|~ zF$`yW^XtABBb2UwKK4rVu0?Kh3lGRCwuoFY3c!@F`#tFnaxo)mnOz{os=G+7Naihv zKvXMHHwR-7=L{$uMV%c-$>TBlI3NbdO64Z2m>H#nr?=sXKMvDaj5FQKyQ6x@T?s2r zjv_@FxKPNsM%8TL9zcu|qDPT_7BTRlU+p=LToBog_x@2$(2m##fzBXn$Fflt@Y z{v&9ne50Mgj-+5;dCiXlfk+mZSlStu)Cyf4-Qq(MIr0(D#;c(rDnB!X#snPSIdTab zPc(=1QrvF_rO9=~%^K1<-}p?CoO^40F)hq5MeqyBIr?Zgr|^!(MXDs)}+*z4Ays98|(9$SpNAq^XK~TAeHMaXsp(qkQOE+*!z8 z@baGG0TpSJCWzGBU6XdisV);m)vZ6GC$4IMJa)=VkQYtKzzyw*DfbUB)pA4AT**;^ z8Zu7S88+(-POOH%VNJ}ozO$S^ZG)(QyPj70tH`R`EaQJ85}eo1M<$b`N@V@Z1i7QP zIY!>#LbpQbPMPWxLn}AcIekOaG)i9H1X;>e9-2hT;00N}yQm3S8V@=#{@JWwYBeN3 zKCJ|1+&#_xs~K-jyBx@Y&0bM+3l<^r4W3dO+Dm*)6KUd>82>8DNjy|`OebCP<~DqX z;`iaZqgxu&(YzP6$WR0$)?{czjI6C|?^(?&>Y=vTa|J}3o}!xdge~QE#OxOud`%=@ zBzpPOSQ?}ryY7g!!=G-BC$05=7;rl2d|5KvBB$N|AeMW?oZRz zq8{$RbYq|rqaZIzi`@DA@lckG&5~hTFT(C>Vjvjo6Zzs{T|&_2L{sFCjpV{4-lvvC z>QM2J>0#5oO36z~IuX$1n$8<`q0OJ*4ci9F4Fjb|C>M9Si&z`Eo$n8nqlX;=3#Qdw zCsMwNb=QfMZ*1LlBIO%Zcb!Q2h9k%F#z@r_o-YX=l+;~UzedSxx_ATO0x3EcN}`3d zi4=bl8x?WNW=Y*arhyDbh4n(|w-oKGGW7Vcilcg z#BeKbA3K}Ih-RhF7i_0z*;K6<{$e;Q;zIh`1X-_WvGrhL!*~R)*BP8t4#!d@y7qU< z{sk$2NzZ@x_v6GTw_lc{69$uH&i1hC4_;I#|15DYt`8 znn;Kt15wfw7o0>&M4BMFd-v`hEbgwe+(|ke1t`J3>wY`~lR6oapR^UT3-_iWDyEbJK>36%r4HvHSyc_pv10hCUMDXKY({Q0569nffZPJ|r;b9PhU8T5(wrSMOhZq%&wsCr$rI?=KN0RF)iy zP3IWhoe3mXtWw{EV7qjVZ3DMer$#P(OLx~$N^m0Iyn&0?k5=BCfqhDM1p7-!z?@yL z3=m?lkM||uMBPrr;sy3joZ^y0PFEwyhnz`d!LYlcH!hF$QA+1hLm%Jk!jLHAyUr-Hl9Y!9bVOM?Oi=eNJnD+c<_6P)u88A zWmw{fVqURQQ)Jv~)1MPtFw)|MM>=trld|ziT$pQ#6UdsG|Nzi;*;@xC{}`R9Fi2~L&#xSZIiOK&$d9UAVTC- z#~BjY@lv!{gNG}1jt-D|6CuA1Qte0I4s}U|<^Y#d9^AQsJbY2nUZ?ze_UvdiTVA_v zHsv20ER$RpdV*v&zELvR2Ei3!(sF z^p9lc^;?D6;!Zq?bW!LDNyD=wf|96sJaHRdcJa6*(BaIG3pZBeU1DO<;QElum-Ucu zX)x+zVMzw037@BHCe}@g8AS!cbMyq968ALho-HR=efwbwr`Xd^YsAKOgIpiM8dlAB4{qre@OR6=tkA?)gna~lFA zOzW-_USFd7#voBE@v3SeE;Ps`196RsL?hd5aD4*jOW8S+W>Onap+cKYfS!<)9m39+ zgt8@r-X$6rcLw8y`3X5MH{Z>QVMgPf8HvOU?4Q(NBG1S7p5;#5xp*wG)Hf{nu#`%C z%!PC;EGJ3zZ`0g@yJ}UvNJv2&`BwSKU419Ee+dbiT%y_F;(oa6jTB;>PjQ|+8iWL! zZ%YlWm!409>)L4UKu($HFgI~tfyl*G&vS`ftw-klC=y>j%l&P^LZiopEp+H@Jl|5m z^ODuFV0TQ+VP4%(y8uh14p)QRh_WBe#zuVY1G*P*n^&Yk-J2^W;rp`{qt##w&!v{2 z$N@3|2G9fP03j#4xG|M;N1?{@L~AXu3E1J{)>c*&=aK%a|HM!&xq_}iqpn4bnnsM0 zf&>l<%#BLaO+Xp2aZb#{4>sHpGr!}!ctP-*boCp*TzaveS3g1Jak~3&6XkJ>?$@Xx z1snH*e;?2V90fiG&H(3ttGV23_s<8n&BL9{e__huEm*AX#2&G(J#l~i!3dfieUe~bTqx^!;-k;tRRrd+`R>*o z1v5nAwo}~k!ZuNPYsfuRBr4;$qB-Inr?}HasiXIt!Y#Y@=llF4am*%!8`^NA!4bFf z6gR4Pji{{k(c(kmak4^6{$)NT{{@&^0Dl4-fWHB*LauV*4>n@rp;+oNf(OeR{$nj( zE?9fljH_KHp@Io~aG8`kI45>k6X6RURL2r}&*$N+HVk%(+g7TP64{5{`z725rMPl% z-;`=*lCGLJdxo$!Qo}Dz{Q4X=tDltyukk+9#+Y3qpLUnjKOCJ*MQauGusiH*GfG48?GXr+raBaV_&U+NtiseT{3g|+Fq=N8Y(6P~WL z2hkHsA@$I>C5sQmra=Mr3AJ!wQ;{?CSEVDMbbmj1g&!pFQerv)tAtbMPpBdPyd}Rb^j}5w8EfAscR)dDfdc_^dbHLtY_Al=y0r za4+05$_ z!j61N-e6!Dyaf4Q?*X{m%4Jz;@U?$VQIS`)FyG?>=YH~DmfW!Wgvt1%p%lW?Goh#` z-;)CdLc1)`66+^`7qP@WRGxyT%x&e#qY35w=kN=jtP>kPLdEBVP2lA}x6&E)X9VC*}Y*sQf#Wu;& z!Q+7U<98I{{Sq8Ygw8)dIK8c8dW)1~df*LZDf2NQ!pvr=$WOJwZmHA7`|-nCFE`=7 z!ck=6)=nSMiU&UO!iwTH-uKFwDJKy{I76OCu?eULY5*Tl36uk+E4WWx*-65XJki_^ z90j^paK_y766gJ}C3@2JRtnk%ExY-o%LWM+5$48X)T@CVz<)gHocD8=a?`{pQu1gu zk%OI=A<+*=(3Am5Kr)~PGPqaopPLl5#)Wn<-~npx=Mq-V7t-(==kGFi)ylOA5(JWv zv&phaxyvinNamv-82j%fvL9Fj^1cV2$4~U7RXL-jSou(vwC7NG-sPg)XprzUHY(Rq zl_ZjKC#vR(Xil~2j>#m^ua3cE4SN^|2aXRMw&eK0S+y~^Pb~bhY$c0xaz1=_J zsYT+7oa{t$Z*IrW$ap{JACDjj83--1|2G7wcTB{%53IT)Z6vp`3L+Acj0m=?f*lgu z4jjKV-|CLMO%vipwxi>^aCYIY#wD&Edq*S5haW8Nj4Z+X^;#Qw#-x0)=jY)4p750Z z7Ex;LSbeLl7MdQEPwVLDiw(BpceB-G)J_b89fSwY)e~qv{PBMgs=G-jo$FjZL6pvY zvzk@zgV9CU*)p;qHYvWz+12(X7g{qHZ<;?^qZT%dE1V_6Pfs2deoDkWmF#83xmLL^ zRvgfyfx~l_XAklU)<9TU>(9RX@M{6;o*n2eB0nBC6HcGY(-`gW)R3~-M0A~KW>7Sd zI?~H6{BiPs5Wa*a(uG})#(btuqO3)vB!N? zZI%ibzhvBF)axcKO2hi`bEMu8k#nzOZP}P`riuI(Le`aBQpi>QcS;bz;mkV1lui~u zzsM`rosMJ@ac|5LvyDXT`bF-h_Aj}Y)=imCVw05&i3W`d5+Gnq{g4Q~o9Bf_Nl-n6 zy2A=d?x%Ha69ff5fx=2!un0@8IAuX!i3_i0t_mXD#}7G^qH0>)k(ba}QZmPiy~3sa zVb=&Ub$8L4)okaWbH4b4W_U6p0xlkgP2ZYQQy_}&chm1OM8m`Dhs$B)04JBQek}I? z)b-`q+mEfk;}){SK^s|GDj@MvJ&ImFe&3heh4u5qD6D}Q;PVFV{$G5fqkNwRN(rB- zHWjN|T$?e4gv9#c?)->Jm_*MooCZQbOguOc4;4Z@yisd`#KqbzlD)95wc~Y5V&J7` zDQeF)irNnx13m>Jz-6Ex82L0sO$D4lDc}P(11|w>z;WPn;CrAS81@WBDFHQL0kVO$ z+bOCZ7>Tha05o6+?tGRCP{pW}18aeLpb>Zm*nz=cL%9z)3VaHD4~U^?955BI1I2&` zcpP{E*b8(49|Grq>wxl46g2~w1C#-4fjDh>ts9?sK{ToODKd2QvzQp$ zNKrNL?%-z#ysGAMpStz`_h2aee-{i#ML7@LyR>r7>WT{P>b8kWr8uu*Y5APxl@$~< zmYQApz?zEer7O!TIs4OV=?+m&#nQDEvsW+oEr(Ek#l61e53EE)ii?&m_sw}=^*n#2 zZ+TT^#e#dhpsnHPXU1^Ho;FR>P_tK8EcI1nt*uz;n@Lf#2imUXRT#%7x}(D9u2{W> zC~Lj{nL8v~Xo;8n&m~#;4-wk9uv7SHO+Yo;+ktkVmjp0CN;#fC8k6v2%vhZBIOasU+VMtp&n=gz5=SAj#+dN<2}z)RD}I0i$5xcYCmxjePZ25;B^h6d z60V>k93{uY7uAIl|M)>|L#aerhH^AY6Us3tDU@&-br>ThquhbA8f7EObtr35K7_Ig zWj{sTN>!r5qoWjMH#r;d>Hf0ynGudG}kn7+Ia0qtxD_E7HF4fAJm4mFKgSihqNDQ zzt)b|rRhw%Y+aRZlWvRdm`nG}G>D~Hu`hfle{Wtm^{jG*%gTufZB*w`` zvoXh5Y^*f48M};ko0gaY>rCrS*GvuOUFQEbUp8MiCt55Pr{!)-z`|L!S-!CRw}rA! zv(nZK8)I|Z7TUhICEIVa>+G5K#rD1SkL{=J=j>PQLmeX>YR3$R#gXkOa1=XA9c7Mk z#|w@&$6?3&4oZc8XhOV>qQ}zX>6!Fgx{O{%uc3o6WiE+E}W8jm2Sk+R|&eV(GE|XcaL-nIvWmqhh8q zfmzHQOfIv6S;y2dk23#Y&M+ohzU>~{dfNuuX4{jt=WH+8UbDSv>$JUV`^a|McF}gt zCbAE;kFcxl>Gl%4&t7leX#X$!5&H@ISN1D*-ag!6b1ZNyb_5&^j+Y!Qj=wtE;f1q~ z%Z{HM6irboctT7MqZRaQdO?6Lq08x&bTz$RSpVbnC-kTECHfle(X7;L()XG0>;Y)aB@w=_+*(>z>rTpxdQ;UH5n0ySk5b7j;*4 zQhloaHpIeC{XYEx{W1MVdX-^@VU^)+L%ZRaVTf^r@fKr1Wt?POWL$2nGS(XZXbc;l zGPWQ%{$@O4JZ9`MUNk#xzg-6S6kk;oVWa7NwY4nUbg;h z9mY&&bc};pz_^)3%)QJ;=1Jx`<|XD0<~`=0%vt6K=3h)dGt?%xDQ)9yYTNC$4BMlQ zCmhcP9Irdxb{s*FoOOKb=yzZ%I4PDD3gAIGd;!MxwW%>SV~uItvF*Tv|Q^kekX^^fUqH(5=0np~zb(^IA<(_c)l znBFwCn~sD&$8K)XjNEeSics+atxWr8?JL@$x?2$QhjpLp z5)6k89~wtzSTb@m4rXk&JZ^c?@{Hv<%L|s5EH7K0wKiEhttYKR896hFDPoo~k1$U$ ze`UUAE-`A`R5-cV_ONY}?OEGH2#8Gy3=R2E*Nk9flVT9fpq$rw!j3{$+?o z@ZDyd889w2zKLL4m$4%P zUDg6?vGoP(F6$m^i*>Jc3})`cCeC48OaZfsc@`n}F>?wVxtlr1M3@UqFJrMeZJD-g zTaInJ?G@W(q_1LZ+(+#{+XK%!A|&XlDC!If3cGR%{b$VoU98$AT7*?oX(ns*8k=Um z#;aMUVX<~CnvXP}X}-~jwUe~3YTwengM>U%m!X@hTc9g6EH;!IstkTZ!0<=IX2Vv) zvzYm-hW8Ag8?G5d#yDfVaX$9iR^u+?d1G22BO{{`x$B*bFESEL6HKM1drcuk>R(L< zO=nE!O!4M1=2UaK*<}9Fe9b)4QeatTky};PJZq`-Ri=xXZJTFXZaZeX#hz@RYF}sn zi(TRv=1@A;I-bIw`T|J@ld7dC^1tOYeSjuc zh~gwh$s{8)tC=(=ouL^$V`3PrZzhvHu)@VmDO1LjbE*HGI;Mr$%d|23n09#LFmseS Sj+O6bYHYQ();jTa>Hh$Z#D|&y diff --git a/core/org.eclipse.cdt.core.win32/os/win32/x86/starter.exe b/core/org.eclipse.cdt.core.win32/os/win32/x86/starter.exe index 38dd37c649d7741c98d03eb70db8ada3701ed75a..a51e76dc846a5a774ad8cf9c4280e0097e6ea806 100644 GIT binary patch delta 1849 zcmc&!Uu+X~9RFQgSb;6AtTi=&wA&3f-AKtggVMz!?d+0H@49Y79m-@S?PavHyONkx zTXW@M-kNM4;YkyT#23*_M$AYSQp21x;bA)drIN4*9%|+TL7cb%KR>^=1AOq=Yd-h= zem~#;zq@ND!(}quxSLy;X!oXH=^Ul?I}2+VcefPo!cM*1RCowE?yfI9DEW63mLNZK zy9)Oq|0c~Pe=vGD!g5LF5`2UNI6c|4@j1^Lw?s_bCT=|;W-#_LJ8pr5tr zCh9^4D5(j@7Hxqu>Tayl3fvBEm&WOKa+ju>bk}MooW@VgJJP2&5TdMBb@%l4ebAt0 z`5D-%QH&gNdI+`dv3rOzYkcSJgRS|uKAL607u7SRpz}mWNNYYf!+*;`S((f7lTc7> z{f}PWj1kEnUwtU%4%*b(Y0gN<^K*r1}H|Cn=(u4%X;vJMyX3fX* zsgvp$KaDQ>+bW7E7Y%b+7b|P;@a+A56jbW$dA2$lr+6y7wvh(USrs_i@)vuSQC52-2p9=Ke9w_ys_ zQLNzNq5V}Z!mHp-ie-`AZx~coRlW$e+gMQMhP#Rja5_I zED-8-dbNjM?ZcBv@#f>d%1O1w48D(EQSpF-;Bg%4wrX&AMvW51+KsG^o-Qgyk~Fa% z)M_l}EZ_9YTm8wV$0VvWrX@Tes{tX)W;IY6&mxG_Y6k3Ar3)* zL#fH*wV+DPEECikVKddtz!)`B>tM;6E?K7zF@tRc4)|z8gpiXkC`=HC{x~27l>(KzrZPv|+fU%XZI{sB74mUUCrfCJ+NY22KN$ zzy)9d@B;UM^>u_i3$V)z`5N#NZ~%w_$ABy_27C&f0j7aVzzyJcU=^sY$A1P;xmt04 zlxA=iCxChT8c#?wf(h*VPjK&obJ-^xPyerDZ{l9n_BwWIUpihG2>rAcg#81t!J#nmlKqMBfE*SQ@x$Sfk$w2nXR+P#U?qUWm|ZqHV@KkNqXTj@9>a!} z%#P?#c%N2P*Y?y|-NrJef)qB$yl}&BdUV0Z|QqmiV zl9_0_5AhmFy~Pj0a3Tz3;tTbIQ$K{QR(t_*Ze0i!DjO2q7jZgWtv>$lt@VTZ1AM~o zobx-+IluGVhlk|zTt3g0`?%_Szc~5AP?25ktZkvZv8VP6c$Rh5{(>)WwAcQ$_IK63 zhd;65t8KvFsO+`&BS$AyvzPv}q##k4YanN0`2P9THrqtY{Q5XIXUNBDxtD*uxL9dAN;Yb5t?1_8M&sV>IvfoKV$rLfQ|$uY8iT#QN!!UE>TC=$c%bfM~a zrFrgar1X9PYy`?8#xtJ4^spf4zBV)3+X`C@3vDr08ij>G16wK7bChm0#o0x)UcEe| zsY52!1~I)=QVDm>csF{b7^&1^GS{ZEOJ;nN8IB6B2;&`Qh!g8RbF#!%t`4$`NMICB zW4~#)1AX|s1A<#dx96t)TQ-G8*b2U)RfZcCJP|ltGM>ZMVhfP9nX29y_aG`~M2_dDM z)R*1pg$4Q-X+UM_MJAdKfy451Yyd*Dx`? z#?lv9`bzz~KNu@4br*xHXc{t(@jILWRIv`xvZKaZ{Jpout$4;0SRAm8HRe{mM8m)l zAOXw)uL7rlvw$D?5x5RG+KD`XxkB)Lz+qqtNCD3RF9NRtr+|-uFMt|Q2iAc*c5e1F zEXf_XkEU=B70+hUwEIv*9-`lYttBDnH{SQ$^}ijrk$XVVf*Io>@6H2XapB}-G#*MR z3jNAGoYrR2ny4H}PmgG+qlxJOqIW5jOg$CV4l1*=(P;&ld(8fDbXE(dQpuDN_xg8l zr@?q~RvC&Wrs4`Iwh;_?T1ntvO{Bq;64ewbm7Ija02$lbeT&2GXPw3jcjw|n_sM2M HvPpjfl9sk0