diff options
Diffstat (limited to 'core/org.eclipse.cdt.core.win32/library')
17 files changed, 1 insertions, 2460 deletions
diff --git a/core/org.eclipse.cdt.core.win32/library/.gitignore b/core/org.eclipse.cdt.core.win32/library/.gitignore index 4d4ec54ac04..2105ba251e3 100644 --- a/core/org.eclipse.cdt.core.win32/library/.gitignore +++ b/core/org.eclipse.cdt.core.win32/library/.gitignore @@ -1,3 +1,4 @@ +/build /ipch/ *.obj *.idb diff --git a/core/org.eclipse.cdt.core.win32/library/Makefile b/core/org.eclipse.cdt.core.win32/library/Makefile deleted file mode 100644 index 76bb655800f..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -# makefile for libspawner.so - -ifeq ($(JAVA_HOME),) -$(error JAVA_HOME not set in environment) -endif - -# Defaults which can be overridden. -OS = win32 -ARCH = x86 - -JDK_INCLUDES= "$(JAVA_HOME)/include" -JDK_OS_INCLUDES= "$(JAVA_HOME)/include/$(OS)" - -CC=g++ -DEBUG_FLAGS = -D_UNICODE -DDEBUG_MONITOR -DREAD_REPORT -CFLAGS = -DUNICODE -I$(JDK_INCLUDES) -I$(JDK_OS_INCLUDES) -CXX=g++ -CXXFLAGS=$(CFLAGS) - -INSTALL_DIR = ../../org.eclipse.cdt.core.$(OS).$(ARCH)/os/$(OS)/$(ARCH) - -LIB_NAME_SPAWNER = spawner.dll -LIB_NAME_FULL_SPAWNER = $(INSTALL_DIR)/spawner.dll -OBJS_SPAWNER=StdAfx.o Win32ProcessEx.o iostream.o raise.o spawner.o - -all: $(LIB_NAME_FULL_SPAWNER) - -rebuild: clean all - -$(LIB_NAME_FULL_SPAWNER) : $(OBJS_SPAWNER) - $(CC) -Wl,--kill-at -shared -o $(LIB_NAME_FULL_SPAWNER) $(OBJS_SPAWNER) -lpsapi - -clean : - $(RM) $(OBJS_SPAWNER) diff --git a/core/org.eclipse.cdt.core.win32/library/Makefile_x86_64.mk b/core/org.eclipse.cdt.core.win32/library/Makefile_x86_64.mk deleted file mode 100644 index aeb5c889190..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/Makefile_x86_64.mk +++ /dev/null @@ -1,60 +0,0 @@ -#******************************************************************************* -# Copyright (c) 2011 Marc-Andre Laperle -# -# This program and the accompanying materials -# are made available under the terms of the Eclipse Public License 2.0 -# which accompanies this distribution, and is available at -# https://www.eclipse.org/legal/epl-2.0/ -# -# SPDX-License-Identifier: EPL-2.0 -# -# Contributors: -# Marc-Andre Laperle - initial API and implementation -#******************************************************************************* - -# Makefile (nmake) for Core fragment on Windows x86_64 - -OS = win32 -ARCH = x86_64 - -JDK_INCLUDES= "$(JAVA_HOME)\include" -JDK_OS_INCLUDES= "$(JAVA_HOME)\include/$(OS)" - -CC=cl -DEBUG_FLAGS = -DDEBUG_MONITOR -DREAD_REPORT -CFLAGS = /TP /I$(JDK_INCLUDES) /I$(JDK_OS_INCLUDES) /EHs /nologo -CFLAGS_UNICODE = /D "_UNICODE" /D "UNICODE" $(CFLAGS) - -INSTALL_DIR = ..\..\org.eclipse.cdt.core.$(OS).$(ARCH)\os\$(OS)\$(ARCH) - -DLL_SPAWNER = spawner.dll -OBJS_SPAWNER=StdAfx.obj Win32ProcessEx.obj iostream.obj raise.obj spawner.obj - -EXE_STARTER = starter.exe -OBJS_STARTER=starter/starter.obj - -.c.obj: - cl /c $(CFLAGS_UNICODE) $*.c /Fo$@ - -.cpp.obj: - cl /c $(CFLAGS_UNICODE) $*.cpp /Fo$@ - -spawner: $(OBJS_SPAWNER) - link /dll /nologo /out:$(DLL_SPAWNER) $(OBJS_SPAWNER) User32.lib - -starter: $(OBJS_STARTER) - link /nologo /out:$(EXE_STARTER) $(OBJS_STARTER) Psapi.Lib Shell32.lib - -all: spawner starter - -clean: - del *.obj *.lib *.exp *.exe *.dll starter\*.obj - -rebuild: clean all - -install: all - copy *.dll $(INSTALL_DIR) - copy *.exe $(INSTALL_DIR) - -uninstall: - del $(INSTALL_DIR)\*.dll $(INSTALL_DIR)\*.exe diff --git a/core/org.eclipse.cdt.core.win32/library/Readme64.txt b/core/org.eclipse.cdt.core.win32/library/Readme64.txt deleted file mode 100644 index 2fb8b08feee..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/Readme64.txt +++ /dev/null @@ -1,26 +0,0 @@ -#******************************************************************************* -# Copyright (c) 2011 Marc-Andre Laperle -# -# This program and the accompanying materials -# are made available under the terms of the Eclipse Public License 2.0 -# which accompanies this distribution, and is available at -# https://www.eclipse.org/legal/epl-2.0/ -# -# SPDX-License-Identifier: EPL-2.0 -# -# Contributors: -# Marc-Andre Laperle - initial API and implementation -#******************************************************************************* - -How to build the Win32 x86_64 core fragment: - -1. Prerequisites -- Install Windows SDK 7.1. If the SDK is not installed in the default location or if you want to try a different SDK, modify setenv64.bat accordingly. -- Make sure your JAVA_HOME environment variable is set and points to a 64 bit JDK (C:\Program Files\Java\jdkX.X.X not C:\Program Files (x86)\Java\jdkX.X.X ) - -2. Build and install -- In a command prompt, execute setenv64.bat. -The command prompt should turn to a different color and print a message about targeting x64. -- Execute build64.bat -This will build the dlls and executables, copy them to org.eclipse.cdt.core.win32.x86_64\os\win32\x86_64 then clean the build directories. -Optionally, you can use nmake /f Makefile_x86_64.mk TARGET directly. Refer to Makefile_x86_64.mk for valid targets. diff --git a/core/org.eclipse.cdt.core.win32/library/Spawner.h b/core/org.eclipse.cdt.core.win32/library/Spawner.h deleted file mode 100644 index 0e10a7b0af5..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/Spawner.h +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2002, 2010 QNX Software Systems and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * QNX Software Systems - initial API and implementation - * - * Spawner.h - * - * This is a part of JNI implementation of spawner - *******************************************************************************/ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include <jni.h> -/* Header for class org_eclipse_cdt_utils_spawner_Spawner */ - -#ifndef _Included_org_eclipse_cdt_utils_spawner_Spawner -#define _Included_org_eclipse_cdt_utils_spawner_Spawner -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_eclipse_cdt_utils_spawner_Spawner - * Method: exec0 - * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[I)I - */ -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0 - (JNIEnv *, jobject, jobjectArray, jobjectArray, jstring, jintArray); - -/* - * Class: org_eclipse_cdt_utils_spawner_Spawner - * Method: exec1 - * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)I - */ -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1 - (JNIEnv *, jobject, jobjectArray, jobjectArray, jstring); - -/* - * Class: org_eclipse_cdt_utils_spawner_Spawner - * Method: exec2 - * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;LILjava/lang/String;IZ)I - */ -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2 - (JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir, jintArray channels, jstring slaveName, jint fdm, jboolean console); - -/* - * Class: org_eclipse_cdt_utils_spawner_Spawner - * Method: raise - * Signature: (II)I - */ -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise - (JNIEnv *, jobject, jint, jint); - - -/* - * Class: org_eclipse_cdt_utils_spawner_Spawner - * Method: waitFor - * Signature: (I)I - */ -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 deleted file mode 100644 index 294977dfd31..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/SpawnerInputStream.h +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2002, 2007 QNX Software Systems and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * QNX Software Systems - initial API and implementation - * - * SpawnerInputStream.h - * - * This is a part of JNI implementation of spawner - *******************************************************************************/ - -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include <jni.h> -/* Header for class com_qnx_tools_utils_spawner_SpawnerInputStream */ - -#ifndef _Included_com_qnx_tools_utils_spawner_SpawnerInputStream -#define _Included_com_qnx_tools_utils_spawner_SpawnerInputStream -#ifdef __cplusplus -extern "C" { -#endif -#undef com_qnx_tools_utils_spawner_SpawnerInputStream_SKIP_BUFFER_SIZE -#define com_qnx_tools_utils_spawner_SpawnerInputStream_SKIP_BUFFER_SIZE 2048L -/* Inaccessible static: skipBuffer */ -/* - * Class: com_qnx_tools_utils_spawner_SpawnerInputStream - * Method: read0 - * Signature: (I[BI)I - */ -JNIEXPORT jint JNICALL Java_com_qnx_tools_utils_spawner_SpawnerInputStream_read0 - (JNIEnv *, jobject, jint, jbyteArray, jint); - -/* - * Class: com_qnx_tools_utils_spawner_SpawnerInputStream - * Method: close0 - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_com_qnx_tools_utils_spawner_SpawnerInputStream_close0 - (JNIEnv *, jobject, jint); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/core/org.eclipse.cdt.core.win32/library/SpawnerOutputStream.h b/core/org.eclipse.cdt.core.win32/library/SpawnerOutputStream.h deleted file mode 100644 index 4ed58014d39..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/SpawnerOutputStream.h +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2002, 2007 QNX Software Systems and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * QNX Software Systems - initial API and implementation - * - * SpawnerOutputStream.h - * - * This is a part of JNI implementation of spawner - *******************************************************************************/ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include <jni.h> -/* Header for class com_qnx_tools_utils_spawner_SpawnerOutputStream */ - -#ifndef _Included_com_qnx_tools_utils_spawner_SpawnerOutputStream -#define _Included_com_qnx_tools_utils_spawner_SpawnerOutputStream -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: com_qnx_tools_utils_spawner_SpawnerOutputStream - * Method: write0 - * Signature: (I[BI)I - */ -JNIEXPORT jint JNICALL Java_com_qnx_tools_utils_spawner_SpawnerOutputStream_write0 - (JNIEnv *, jobject, jint, jbyteArray, jint); - -/* - * Class: com_qnx_tools_utils_spawner_SpawnerOutputStream - * Method: close0 - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_com_qnx_tools_utils_spawner_SpawnerOutputStream_close0 - (JNIEnv *, jobject, jint); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/core/org.eclipse.cdt.core.win32/library/StdAfx.c b/core/org.eclipse.cdt.core.win32/library/StdAfx.c deleted file mode 100644 index ea8e1023e93..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/StdAfx.c +++ /dev/null @@ -1,25 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2002, 2007 QNX Software Systems and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * 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 -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/core/org.eclipse.cdt.core.win32/library/StdAfx.h b/core/org.eclipse.cdt.core.win32/library/StdAfx.h deleted file mode 100644 index c176fed0ad0..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/StdAfx.h +++ /dev/null @@ -1,44 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2002, 2007 QNX Software Systems and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * 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 -// - -#if !defined(AFX_STDAFX_H__9D84F180_36E5_47D6_96AB_22723242789C__INCLUDED_) -#define AFX_STDAFX_H__9D84F180_36E5_47D6_96AB_22723242789C__INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif // _MSC_VER > 1000 - - -// Insert your headers here -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers - -#include <tchar.h> - -#include <windows.h> - -// TODO: reference additional headers your program requires here - -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - -#endif // !defined(AFX_STDAFX_H__9D84F180_36E5_47D6_96AB_22723242789C__INCLUDED_) diff --git a/core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c b/core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c deleted file mode 100644 index 1554983330a..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/Win32ProcessEx.c +++ /dev/null @@ -1,1009 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2002, 2015 QNX Software Systems and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * QNX Software Systems - initial API and implementation - * Wind River Systems, Inc. - * - * Win32ProcessEx.c - * - * This is a JNI implementation of spawner - *******************************************************************************/ - -#include "stdafx.h" -#include <string.h> -#include <stdlib.h> -#include <process.h> -#include "Spawner.h" - -#include "jni.h" -#include "io.h" - - -#define PIPE_SIZE 512 // Size of pipe buffer -#define MAX_CMD_SIZE 2049 // Initial 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. - -#define MAX_PROCS (100) // Maximum number of simultaneously running processes - - -// Process description block. Should be created for each launched process -typedef struct _procInfo { - int pid; // 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. - // 4 events connected to this process (see starter) - HANDLE eventBreak; // signaled when Spawner.interrupt() is called; mildest of the terminate requests (SIGINT signal in UNIX world) - HANDLE eventWait; - HANDLE eventTerminate; // signaled when Spawner.terminate() is called; more forceful terminate request (SIGTERM signal in UNIX world) - HANDLE eventKill; // signaled when Spawner.kill() is called; most forceful terminate request (SIGKILL signal in UNIX world) - HANDLE eventCtrlc; // signaled when Spawner.interruptCTRLC() is called; like interrupt() but sends CTRL-C in all cases, even when inferior is a Cygwin program -} procInfo_t, * pProcInfo_t; - -static int procCounter = 0; // Number of running processes - - -// This is a VM helper -void ThrowByName(JNIEnv *env, const char *name, const char *msg); - -// Creates _procInfo block for every launched process -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 -void _cdecl waitProcTermination(void* pv) ; - -// This is a helper function to prevent losing of quotation marks -static int copyTo(wchar_t * target, const wchar_t * 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, - SIG_INT, - SIG_KILL = 9, - SIG_TERM = 15, - CTRLC = 1000 // special, Windows only. Sends CTRL-C in all cases, even when inferior is a Cygwin program -} signals; - -extern CRITICAL_SECTION cs; - - -extern wchar_t path[MAX_PATH]; // Directory where spawner.dll is located - -static HMODULE hVM = NULL; // VM handler - - -static pProcInfo_t pInfo = NULL; - -static int nCounter = 0; // We use it to build unique synchronization 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 -///////////////////////////////////////////////////////////////////////////////////// - -extern "C" -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2 - (JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir, jintArray channels, jstring slaveName, jint fdm, jboolean console) -{ - return -1; -} - -void ensureSize(wchar_t** ptr, int* psize, int requiredLength) -{ - int size= *psize; - if (requiredLength > size) { - size= 2*size; - if (size < requiredLength) { - size= requiredLength; - } - *ptr= (wchar_t *)realloc(*ptr, size * sizeof(wchar_t)); - if (NULL == *ptr) { - *psize= 0; - } - else { - *psize= size; - } - } -} - -extern "C" -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0 - (JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir, jintArray channels) -{ - HANDLE stdHandles[3]; - PROCESS_INFORMATION pi = {0}, *piCopy; - STARTUPINFOW si; - DWORD flags = 0; - const wchar_t * cwd = NULL; - LPVOID envBlk = NULL; - int ret = 0; - int nCmdLineLength= 0; - wchar_t * szCmdLine= 0; - int nBlkSize = MAX_ENV_SIZE; - wchar_t * szEnvBlock = NULL; - jsize nCmdTokens = 0; - jsize nEnvVars = 0; - int i; - DWORD pid = GetCurrentProcessId(); - int nPos; - pProcInfo_t pCurProcInfo; - - // This needs to be big enough to contain the name of the event used when calling CreateEventW bellow. - // It is made of a prefix (7 characters max) plus the value of a pointer that gets output in characters. - // This will be bigger in the case of 64 bit. - static const int MAX_EVENT_NAME_LENGTH = 50; - wchar_t eventBreakName[MAX_EVENT_NAME_LENGTH]; - wchar_t eventWaitName[MAX_EVENT_NAME_LENGTH]; - wchar_t eventTerminateName[MAX_EVENT_NAME_LENGTH]; - wchar_t eventKillName[MAX_EVENT_NAME_LENGTH]; - wchar_t eventCtrlcName[MAX_EVENT_NAME_LENGTH]; -#ifdef DEBUG_MONITOR - wchar_t buffer[4000]; -#endif - int nLocalCounter; - wchar_t inPipeName[PIPE_NAME_LENGTH]; - wchar_t outPipeName[PIPE_NAME_LENGTH]; - wchar_t errPipeName[PIPE_NAME_LENGTH]; - - nCmdLineLength= MAX_CMD_SIZE; - szCmdLine= (wchar_t *)malloc(nCmdLineLength * sizeof(wchar_t)); - szCmdLine[0]= _T('\0'); - if((HIBYTE(LOWORD(GetVersion()))) & 0x80) - { - ThrowByName(env, "java/io/IOException", "Does not support Windows 3.1/95/98/Me"); - return 0; - } - - if (cmdarray == 0) - { - ThrowByName(env, "java/lang/NullPointerException", "No command line specified"); - return 0; - } - - ZeroMemory(stdHandles, sizeof(stdHandles)); - - // Create pipe names - EnterCriticalSection(&cs); - swprintf(inPipeName, L"\\\\.\\pipe\\stdin%08i%010i", pid, nCounter); - swprintf(outPipeName, L"\\\\.\\pipe\\stdout%08i%010i", pid, nCounter); - swprintf(errPipeName, L"\\\\.\\pipe\\stderr%08i%010i", pid, nCounter); - nLocalCounter = nCounter; - ++nCounter; - LeaveCriticalSection(&cs); - - if ((INVALID_HANDLE_VALUE == (stdHandles[0] = CreateNamedPipeW(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] = CreateNamedPipeW(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] = CreateNamedPipeW(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 - swprintf(buffer, _T("Opened pipes: %s, %s, %s\n"), inPipeName, outPipeName, errPipeName); - OutputDebugStringW(buffer); -#endif - - - nCmdTokens = env->GetArrayLength(cmdarray); - nEnvVars = env->GetArrayLength(envp); - - pCurProcInfo = createProcInfo(); - - if(NULL == pCurProcInfo) - { - ThrowByName(env, "java/io/IOException", "Too many processes"); - return 0; - } - - // Construct starter's command line - swprintf(eventBreakName, L"SABreak%04x%08x", pid, nLocalCounter); - swprintf(eventWaitName, L"SAWait%004x%08x", pid, nLocalCounter); - swprintf(eventTerminateName, L"SATerm%004x%08x", pid, nLocalCounter); - swprintf(eventKillName, L"SAKill%04x%08x", pid, nLocalCounter); - swprintf(eventCtrlcName, L"SACtrlc%04x%08x", pid, nLocalCounter); - - pCurProcInfo->eventBreak = CreateEventW(NULL, FALSE, FALSE, eventBreakName); - if(NULL == pCurProcInfo->eventBreak || GetLastError() == ERROR_ALREADY_EXISTS) - { - ThrowByName(env, "java/io/IOException", "Cannot create event"); - return 0; - } - pCurProcInfo->eventWait = CreateEventW(NULL, TRUE, FALSE, eventWaitName); - pCurProcInfo->eventTerminate = CreateEventW(NULL, FALSE, FALSE, eventTerminateName); - pCurProcInfo->eventKill = CreateEventW(NULL, FALSE, FALSE, eventKillName); - pCurProcInfo->eventCtrlc = CreateEventW(NULL, FALSE, FALSE, eventCtrlcName); - - swprintf(szCmdLine, L"\"%sstarter.exe\" %i %i %s %s %s %s %s ", path, pid, nLocalCounter, eventBreakName, eventWaitName, eventTerminateName, eventKillName, eventCtrlcName); - nPos = wcslen(szCmdLine); - - // Prepare command line - for(i = 0; i < nCmdTokens; ++i) - { - jstring item = (jstring)env->GetObjectArrayElement(cmdarray, i); - jsize len = env->GetStringLength(item); - int nCpyLen; - const wchar_t * str = (const wchar_t *)env->GetStringChars(item, 0); - if(NULL != str) - { - int requiredSize= nPos+len+2; - if (requiredSize > 32*1024) { - ThrowByName(env, "java/io/IOException", "Command line too long"); - return 0; - } - ensureSize(&szCmdLine, &nCmdLineLength, requiredSize); - if (NULL == szCmdLine) { - ThrowByName(env, "java/io/IOException", "Not enough memory"); - return 0; - } - - if(0 > (nCpyLen = copyTo(szCmdLine + nPos, str, len, nCmdLineLength - nPos))) - { - ThrowByName(env, "java/io/IOException", "Command line too long"); - return 0; - } - nPos += nCpyLen; - szCmdLine[nPos] = _T(' '); - ++nPos; - env->ReleaseStringChars(item, (const jchar *)str); - } - } - szCmdLine[nPos] = _T('\0'); - -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("There are %i environment variables \n"), nEnvVars); - OutputDebugStringW(buffer); -#endif - // Prepare environment block - if (nEnvVars > 0) - { - nPos = 0; - szEnvBlock = (wchar_t *)malloc(nBlkSize * sizeof(wchar_t)); - for(i = 0; i < nEnvVars; ++i) - { - jstring item = (jstring)env->GetObjectArrayElement(envp, i); - jsize len = env->GetStringLength(item); - const wchar_t * str = (const wchar_t *)env->GetStringChars(item, 0); - if(NULL != str) - { - while((nBlkSize - nPos) <= (len + 2)) // +2 for two '\0' - { - nBlkSize += MAX_ENV_SIZE; - szEnvBlock = (wchar_t *)realloc(szEnvBlock, nBlkSize * sizeof(wchar_t)); - if(NULL == szEnvBlock) - { - ThrowByName(env, "java/io/IOException", "Not enough memory"); - return 0; - } -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("Realloc environment block; new length is %i \n"), nBlkSize); - OutputDebugStringW(buffer); -#endif - - } -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("%s\n"), str); - OutputDebugStringW(buffer); -#endif - wcsncpy(szEnvBlock + nPos, str, len); - nPos += len; - szEnvBlock[nPos] = _T('\0'); - ++nPos; - env->ReleaseStringChars(item, (const jchar *)str); - } - } - szEnvBlock[nPos] = _T('\0'); - } - - - - if (dir != 0) - { - const wchar_t * str = (const wchar_t *)env->GetStringChars(dir, 0); - if(NULL != str) - { - cwd = wcsdup(str); - env->ReleaseStringChars(dir, (const jchar *)str); - } - } - - - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - si.dwFlags |= STARTF_USESHOWWINDOW; - si.wShowWindow = SW_HIDE; // Processes in the Process Group are hidden - - - - 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; - flags |= CREATE_UNICODE_ENVIRONMENT; - -#ifdef DEBUG_MONITOR - OutputDebugStringW(szCmdLine); -#endif - // launches starter; we need it to create another console group to correctly process - // emulation of SYSint signal (Ctrl-C) - ret = CreateProcessW(0, /* executable name */ - szCmdLine, /* command line */ - 0, /* process security attribute */ - 0, /* thread security attribute */ - FALSE, /* inherits system handles */ - flags, /* normal attached process */ - szEnvBlock, /* environment block */ - cwd, /* change to the new current directory */ - &si, /* (in) startup information */ - &pi); /* (out) process information */ - - if(NULL != cwd) - free((void *)cwd); - - if(NULL != szEnvBlock) - free(szEnvBlock); - - if(NULL != szCmdLine) - free(szCmdLine); - - if (!ret) // Launching error - { - char * lpMsgBuf; - CloseHandle(stdHandles[0]); - CloseHandle(stdHandles[1]); - CloseHandle(stdHandles[2]); - FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (char *)&lpMsgBuf, - 0, - NULL - ); - ThrowByName(env, "java/io/IOException", lpMsgBuf); - // Free the buffer. - LocalFree( lpMsgBuf ); - cleanUpProcBlock(pCurProcInfo); - ret = -1; - } - else - { - int file_handles[3]; - HANDLE h[2]; - int what; - - EnterCriticalSection(&cs); - - pCurProcInfo -> pid = pi.dwProcessId; - h[0] = pCurProcInfo -> eventWait; - h[1] = pi.hProcess; - - what = WaitForMultipleObjects(2, h, FALSE, INFINITE); - if(what != WAIT_OBJECT_0) // CreateProcess failed - { -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("Process %i failed\n"), pi.dwProcessId); - OutputDebugStringW(buffer); -#endif - cleanUpProcBlock(pCurProcInfo); - ThrowByName(env, "java/io/IOException", "Launching failed"); -#ifdef DEBUG_MONITOR - OutputDebugStringW(_T("Process failed\n")); -#endif - } - else - { - ret = (long)(pCurProcInfo -> uid); - - // 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(channels, 0, 3, (jint *)file_handles); - - // do the cleanup so launch the according thread - // create a copy of the PROCESS_INFORMATION as this might get destroyed - piCopy = (PROCESS_INFORMATION *)malloc(sizeof(PROCESS_INFORMATION)); - memcpy(piCopy, &pi, sizeof(PROCESS_INFORMATION)); - _beginthread(waitProcTermination, 0, (void *)piCopy); - -#ifdef DEBUG_MONITOR - OutputDebugStringW(_T("Process started\n")); -#endif - } - LeaveCriticalSection(&cs); - - } - - CloseHandle(pi.hThread); - - return ret; - -} - - -///////////////////////////////////////////////////////////////////////////////////// -// 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 -///////////////////////////////////////////////////////////////////////////////////// -extern "C" -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1 - (JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir) -{ - - SECURITY_ATTRIBUTES sa; - PROCESS_INFORMATION pi = {0}; - STARTUPINFOW si; - DWORD flags = 0; - wchar_t * cwd = NULL; - wchar_t * envBlk = NULL; - int ret = 0; - jsize nCmdTokens = 0; - jsize nEnvVars = 0; - int i; - int nPos; - int nCmdLineLength= 0; - wchar_t * szCmdLine= 0; - int nBlkSize = MAX_ENV_SIZE; - wchar_t * szEnvBlock = NULL; - - nCmdLineLength= MAX_CMD_SIZE; - szCmdLine= (wchar_t *)malloc(nCmdLineLength * sizeof(wchar_t)); - szCmdLine[0]= 0; - - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = 0; - sa.bInheritHandle = TRUE; - - - nCmdTokens = env->GetArrayLength(cmdarray); - nEnvVars = env->GetArrayLength(envp); - - nPos = 0; - - // Prepare command line - for(i = 0; i < nCmdTokens; ++i) - { - jstring item = (jstring)env->GetObjectArrayElement(cmdarray, i); - jsize len = env->GetStringLength(item); - int nCpyLen; - const wchar_t * str = (const wchar_t *)env->GetStringChars(item, 0); - if(NULL != str) - { - int requiredSize= nPos+len+2; - if (requiredSize > 32*1024) { - ThrowByName(env, "java/io/IOException", "Command line too long"); - return 0; - } - ensureSize(&szCmdLine, &nCmdLineLength, requiredSize); - if (NULL == szCmdLine) { - ThrowByName(env, "java/io/IOException", "Not enough memory"); - return 0; - } - - if(0 > (nCpyLen = copyTo(szCmdLine + nPos, str, len, nCmdLineLength - nPos))) - { - ThrowByName(env, "java/io/Exception", "Command line too long"); - return 0; - } - nPos += nCpyLen; - szCmdLine[nPos] = _T(' '); - ++nPos; - env->ReleaseStringChars(item, (const jchar *)str); - } - } - - szCmdLine[nPos] = _T('\0'); - - // Prepare environment block - if (nEnvVars > 0) - { - szEnvBlock = (wchar_t *)malloc(nBlkSize * sizeof(wchar_t)); - nPos = 0; - for(i = 0; i < nEnvVars; ++i) - { - jstring item = (jstring)env->GetObjectArrayElement(envp, i); - jsize len = env->GetStringLength(item); - const wchar_t * str = (const wchar_t *)env->GetStringChars(item, 0); - if(NULL != str) - { - while((nBlkSize - nPos) <= (len + 2)) // +2 for two '\0' - { - nBlkSize += MAX_ENV_SIZE; - szEnvBlock = (wchar_t *)realloc(szEnvBlock, nBlkSize * sizeof(wchar_t)); - if(NULL == szEnvBlock) - { - ThrowByName(env, "java/io/Exception", "Not enough memory"); - return 0; - } - } - wcsncpy(szEnvBlock + nPos, str, len); - nPos += len; - szEnvBlock[nPos] = _T('\0'); - ++nPos; - env->ReleaseStringChars(item, (const jchar *)str); - } - } - szEnvBlock[nPos] = _T('\0'); - envBlk = szEnvBlock; - } - - - - if (dir != 0) - { - const wchar_t * str = (const wchar_t *)env->GetStringChars(dir, 0); - if(NULL != str) - { - cwd = wcsdup(str); - env->ReleaseStringChars(dir, (const jchar *)str); - } - } - - - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - - - - - - flags = CREATE_NEW_CONSOLE; - flags |= CREATE_UNICODE_ENVIRONMENT; - ret = CreateProcessW(0, /* executable name */ - szCmdLine, /* command line */ - 0, /* process security attribute */ - 0, /* thread security attribute */ - TRUE, /* inherits system handles */ - flags, /* normal attached process */ - envBlk, /* environment block */ - cwd, /* change to the new current directory */ - &si, /* (in) startup information */ - &pi); /* (out) process information */ - - - - if(NULL != cwd) - free(cwd); - if(NULL != szEnvBlock) - free(szEnvBlock); - if(NULL != szCmdLine) - free(szCmdLine); - - if (!ret) // error - { - char * lpMsgBuf; - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (wchar_t *)&lpMsgBuf, - 0, - NULL - ); - ThrowByName(env, "java/io/IOException", lpMsgBuf); - // Free the buffer. - LocalFree( lpMsgBuf ); - ret = -1; - } - else - { - // Clean-up - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - ret = (long)pi.dwProcessId; //hProcess; - } - - - return ret; - -} - - -///////////////////////////////////////////////////////////////////////////////////// -// Emulation of the signal raising -// Arguments: (see Spawner.java) -// [in] uid - unique process ID -// [in] signal - signal to raise -///////////////////////////////////////////////////////////////////////////////////// -extern "C" -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise - (JNIEnv * env, jobject process, jint uid, jint signal) -{ - jint ret = 0; - - HANDLE hProc; - pProcInfo_t pCurProcInfo = findProcInfo(uid); -#ifdef DEBUG_MONITOR - wchar_t buffer[100]; -#endif - - if(NULL == pCurProcInfo) { - if(SIG_INT == signal) { // Try another way - return interruptProcess(uid) ; - } - return -1; - } - -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("Spawner received signal %i for process %i\n"), signal, pCurProcInfo -> pid); - OutputDebugStringW(buffer); -#endif - - hProc = OpenProcess(SYNCHRONIZE, 0, pCurProcInfo -> pid); - - if(NULL == hProc) - return -1; - - switch(signal) - { - case SIG_NOOP: - // Wait 0 msec -just check if the process has been still running - ret = ((WAIT_TIMEOUT == WaitForSingleObject(hProc, 0)) ? 0 : -1); - break; - case SIG_HUP: - // Temporary do nothing - ret = 0; - break; - case SIG_TERM: -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("Spawner received TERM signal for process %i\n"), - pCurProcInfo -> pid); - OutputDebugStringW(buffer); -#endif - SetEvent(pCurProcInfo -> eventTerminate); -#ifdef DEBUG_MONITOR - OutputDebugStringW(_T("Spawner signaled TERM event\n")); -#endif - ret = 0; - break; - - case SIG_KILL: -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("Spawner received KILL signal for process %i\n"), - pCurProcInfo -> pid); - OutputDebugStringW(buffer); -#endif - SetEvent(pCurProcInfo -> eventKill); -#ifdef DEBUG_MONITOR - OutputDebugStringW(_T("Spawner signaled KILL event\n")); -#endif - ret = 0; - break; - case SIG_INT: - ResetEvent(pCurProcInfo -> eventWait); - SetEvent(pCurProcInfo -> eventBreak); - ret = (WaitForSingleObject(pCurProcInfo -> eventWait, 100) == WAIT_OBJECT_0); - break; - case CTRLC: - ResetEvent(pCurProcInfo -> eventWait); - SetEvent(pCurProcInfo -> eventCtrlc); - ret = (WaitForSingleObject(pCurProcInfo -> eventWait, 100) == WAIT_OBJECT_0); - break; - default: - break; - } - - CloseHandle(hProc); - return ret; - - -} - - - -///////////////////////////////////////////////////////////////////////////////////// -// Wait for process termination -// Arguments: (see Spawner.java) -// [in] uid - unique process ID -///////////////////////////////////////////////////////////////////////////////////// -extern "C" -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor - (JNIEnv * env, jobject process, jint uid) -{ - DWORD exit_code = -1; - int what=0; - HANDLE hProc; - pProcInfo_t pCurProcInfo = findProcInfo(uid); - - if(NULL == pCurProcInfo) - return -1; - - hProc = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, 0, pCurProcInfo -> pid); - - if(NULL == hProc) - return -1; - - what = WaitForSingleObject(hProc, INFINITE); - - - if (what == WAIT_OBJECT_0) - { - GetExitCodeProcess(hProc, &exit_code); - } - - - if(hProc) - CloseHandle(hProc); - - 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 -///////////////////////////////////////////////////////////////////////////////////// -void ThrowByName(JNIEnv *env, const char *name, const char *msg) -{ - jclass cls = env->FindClass(name); - - if (cls != 0) /* Otherwise an exception has already been thrown */ - env->ThrowNew(cls, msg); - - /* It's a good practice to clean up the local references. */ - env->DeleteLocalRef(cls); -} - - - - -///////////////////////////////////////////////////////////////////////////////////// -// Create process description block. -// Arguments: no -// Return : pointer to the process descriptor -///////////////////////////////////////////////////////////////////////////////////// -pProcInfo_t createProcInfo() -{ - int i; - pProcInfo_t p = NULL; - - EnterCriticalSection(&cs); - - if(NULL == pInfo) - { - pInfo = (pProcInfo_t)malloc(sizeof(procInfo_t) * MAX_PROCS); - ZeroMemory(pInfo, sizeof(procInfo_t) * MAX_PROCS); - } - - for(i = 0; i < MAX_PROCS; ++i) - { - if(pInfo[i].pid == 0) - { - pInfo[i].pid = -1; - pInfo[i].uid = ++procCounter; - p = pInfo + i; - break; - } - } - - LeaveCriticalSection(&cs); - - return p; -} - -///////////////////////////////////////////////////////////////////////////////////// -// Using unique process ID finds process descriptor -// Arguments: no -// Return : pointer to the process descriptor -///////////////////////////////////////////////////////////////////////////////////// -pProcInfo_t findProcInfo(int uid) -{ - int i; - pProcInfo_t p = NULL; - if(NULL == pInfo) - return NULL; - - for(i = 0; i < MAX_PROCS; ++i) - { - if(pInfo[i].uid == uid) - { - p = pInfo + i; - break; - } - } - - 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) - { - CloseHandle(pCurProcInfo -> eventBreak); - pCurProcInfo -> eventBreak = 0; - } - if(0 != pCurProcInfo -> eventWait) - { - CloseHandle(pCurProcInfo -> eventWait); - pCurProcInfo -> eventWait = 0; - } - if(0 != pCurProcInfo -> eventTerminate) - { - CloseHandle(pCurProcInfo -> eventTerminate); - pCurProcInfo -> eventTerminate = 0; - } - - if(0 != pCurProcInfo -> eventKill) - { - CloseHandle(pCurProcInfo -> eventKill); - pCurProcInfo -> eventKill = 0; - } - - if(0 != pCurProcInfo -> eventCtrlc) - { - CloseHandle(pCurProcInfo -> eventCtrlc); - pCurProcInfo -> eventCtrlc = 0; - } - - pCurProcInfo -> pid = 0; -} - -///////////////////////////////////////////////////////////////////////////////////// -// Running in separate thread and waiting for the process termination -// Arguments: -// pv - pointer to PROCESS_INFORMATION struct -// Return : no -///////////////////////////////////////////////////////////////////////////////////// -void _cdecl waitProcTermination(void* pv) -{ - PROCESS_INFORMATION *pi = (PROCESS_INFORMATION *)pv; - int i; -#ifdef DEBUG_MONITOR - wchar_t buffer[1000]; -#endif - - // wait for process termination - WaitForSingleObject(pi->hProcess, INFINITE); - - for(i = 0; i < MAX_PROCS; ++i) - { - if(pInfo[i].pid == pi->dwProcessId) - { - cleanUpProcBlock(pInfo + i); -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("waitProcTermination: set PID %i to 0\n"), - pi->dwProcessId); - OutputDebugStringW(buffer); -#endif - } - } - CloseHandle(pi->hProcess); - - free(pi); -} - -///////////////////////////////////////////////////////////////////////////////////// -// 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(wchar_t * target, const wchar_t * source, int cpyLength, int availSpace) -{ - BOOL bSlash = FALSE; - int i = 0, j = 0; - int totCpyLength = cpyLength; - -#define QUOTATION_DO 0 -#define QUOTATION_DONE 1 -#define QUOTATION_NONE 2 - - int nQuotationMode = 0; - - - - if(availSpace <= cpyLength) // = to reserve space for final '\0' - return -1; - - if((_T('\"') == *source) && (_T('\"') == *(source + cpyLength - 1))) - { - nQuotationMode = QUOTATION_DONE; - } - else - if(wcschr(source, _T(' ')) == NULL) - { - // No reason to quote term because it doesn't have embedded spaces - nQuotationMode = QUOTATION_NONE; - } - else - { - // Needs to be quoted - nQuotationMode = QUOTATION_DO; - *target = _T('\"'); - ++j; - } - - - for(; i < cpyLength; ++i, ++j) - { - if(source[i] == _T('\\')) - bSlash = TRUE; - else - { - // Don't escape embracing quotation marks - if((source[i] == _T('\"')) && !((nQuotationMode == QUOTATION_DONE) && ((i == 0) || (i == (cpyLength - 1))) ) ) - { - if(!bSlash) // If still not escaped - { - if(j == availSpace) - return -1; - target[j] = _T('\\'); - ++j; - } - } - bSlash = FALSE; - } - - if(j == availSpace) - return -1; - target[j] = source[i]; - } - - if(nQuotationMode == QUOTATION_DO) - { - if(j == availSpace) - return -1; - target[j] = _T('\"'); - ++j; - } - - return j; -} diff --git a/core/org.eclipse.cdt.core.win32/library/build64.bat b/core/org.eclipse.cdt.core.win32/library/build64.bat deleted file mode 100644 index f866c8befc0..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/build64.bat +++ /dev/null @@ -1,14 +0,0 @@ -@rem *************************************************************************** -@rem Copyright (c) 2011 Marc-Andre Laperle and others. -@rem This program and the accompanying materials -@rem are made available under the terms of the Eclipse Public License 2.0 -@rem which accompanies this distribution, and is available at -@rem https://www.eclipse.org/legal/epl-2.0/ -em -em SPDX-License-Identifier: EPL-2.0 -@rem -@rem Contributors: -@rem Marc-Andre Laperle - initial API and implementation -@rem *************************************************************************** - -nmake /f Makefile_x86_64.mk /NOLOGO install clean
\ No newline at end of file diff --git a/core/org.eclipse.cdt.core.win32/library/iostream.c b/core/org.eclipse.cdt.core.win32/library/iostream.c deleted file mode 100644 index 3b8d11259d4..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/iostream.c +++ /dev/null @@ -1,272 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2002, 2009 QNX Software Systems and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * 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) - *******************************************************************************/ -#include "stdafx.h" -#include <string.h> -#include <stdlib.h> -#include "spawner.h" -#include "SpawnerInputStream.h" -#include "SpawnerOutputStream.h" - -#include "jni.h" -#include "io.h" - -//#define READ_REPORT - -void ThrowByName(JNIEnv *env, const char *name, const char *msg); - -#define BUFF_SIZE (1024) - -/* Inaccessible static: skipBuffer */ -/* - * Class: SpawnerInputStream - * Method: read0 - * Signature: (I)I - */ -extern "C" -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_read0 - (JNIEnv * env, jobject proc, jint fd, jbyteArray buf, jint len) -{ - jbyte tmpBuf[BUFF_SIZE]; - int nBuffOffset = 0; -#ifdef DEBUG_MONITOR - _TCHAR 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) { - char * lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (wchar_t *) &lpMsgBuf, - 0, - NULL - ); - - ThrowByName(env, "java/io/IOException", lpMsgBuf); - // Free the buffer. - LocalFree( lpMsgBuf ); - } - -#ifdef DEBUG_MONITOR -#ifdef READ_REPORT - _stprintf(buffer, _T("Start read %i\n"), fd); - OutputDebugStringW(buffer); -#endif -#endif - - while(len > nBuffOffset) - { - DWORD nNumberOfBytesToRead = min(len - nBuffOffset, BUFF_SIZE); - DWORD nNumberOfBytesRead; - if(0 == ReadFile((HANDLE)fd, tmpBuf, nNumberOfBytesToRead, &nNumberOfBytesRead, &overlapped )) - { - 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 - break; - if(err != 0) - { - char * lpMsgBuf; -#ifdef DEBUG_MONITOR - _stprintf(buffer, _T("Read failed - %i, error %i\n"), fd, err); - OutputDebugStringW(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 - (wchar_t *) &lpMsgBuf, - 0, - NULL - ); - - ThrowByName(env, "java/io/IOException", lpMsgBuf); - LocalFree( lpMsgBuf ); - nBuffOffset = 0; - break; - } - else - { - // buffer overflow? - // according to msdn this happens in message read mode only -#ifdef DEBUG_MONITOR - _stprintf(buffer, _T("Buffer full - %i, bytes read: %i\n"), fd, nNumberOfBytesRead); - OutputDebugStringW(buffer); -#endif - // nNumberOfBytesRead can be 0 here for unknown reason (bug 269223) - nNumberOfBytesRead = nNumberOfBytesToRead; - } - } - } - if(nNumberOfBytesRead > 0) - env->SetByteArrayRegion(buf, nBuffOffset, nNumberOfBytesRead, tmpBuf); - else - break; - nBuffOffset += nNumberOfBytesRead; - if(nNumberOfBytesRead != nNumberOfBytesToRead) - break; - else - { - // Is there data left in the pipe? - DWORD bytesAvailable = 0; - if (!::PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &bytesAvailable, NULL) - || bytesAvailable == 0) - // No bytes left - break; - } - } - CloseHandle(overlapped.hEvent); -#ifdef DEBUG_MONITOR -#ifdef READ_REPORT - _stprintf(buffer, _T("End read %i - bytes read: %d\n"), fd, nBuffOffset); - OutputDebugStringW(buffer); -#endif -#endif - return nBuffOffset; // This is a real full readed length - -} - -/* - * Class: SpawnerInputStream - * Method: close0 - * Signature: (I)I - */ -extern "C" -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0 - (JNIEnv * env, jobject proc, jint fd) -{ - int rc; -#ifdef DEBUG_MONITOR - _TCHAR buffer[1000]; - _stprintf(buffer, _T("Close %i\n"), fd); - OutputDebugStringW(buffer); -#endif - rc = (CloseHandle((HANDLE)fd) ? 0 : -1); -#ifdef DEBUG_MONITOR - _stprintf(buffer, _T("Closed %i\n"), fd); - OutputDebugStringW(buffer); -#endif - return (rc ? GetLastError() : 0); -} - -extern "C" -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_available0 - (JNIEnv * env, jobject proc, jint fd) -{ - DWORD nAvail = 0; - - if (0 == PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nAvail, NULL)) { - // error - return 0; - } - return nAvail; -} - -/* - * Class: SpawnerOutputStream - * Method: write0 - * Signature: (I[BI)I - */ -extern "C" -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_write0 - (JNIEnv * env, jobject proc, jint fd, jbyteArray buf, jint len) -{ - jbyte tmpBuf[BUFF_SIZE]; - int nBuffOffset = 0; - - - while(len > nBuffOffset) - { - DWORD nNumberOfBytesToWrite = min(len - nBuffOffset, BUFF_SIZE); - DWORD nNumberOfBytesWritten; - env->GetByteArrayRegion(buf, nBuffOffset, nNumberOfBytesToWrite, tmpBuf); - if(0 == WriteFile((HANDLE)fd, tmpBuf, nNumberOfBytesToWrite, &nNumberOfBytesWritten, NULL)) - { - char * lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (wchar_t *) &lpMsgBuf, - 0, - NULL - ); - - ThrowByName(env, "java/io/IOException", lpMsgBuf); - LocalFree( lpMsgBuf ); - return 0; - } - nBuffOffset += nNumberOfBytesWritten; - } - return 0; -} - -/* - * Class: SpawnerOutputStream - * Method: close0 - * Signature: (I)I - */ -extern "C" -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0 - (JNIEnv * env, jobject proc, jint fd) -{ - int rc; -#ifdef DEBUG_MONITOR - _TCHAR buffer[1000]; - _stprintf(buffer, _T("Close %i\n"), fd); - OutputDebugStringW(buffer); -#endif - FlushFileBuffers((HANDLE)fd); - rc = (CloseHandle((HANDLE)fd) ? 0 : -1); -#ifdef DEBUG_MONITOR - _stprintf(buffer, _T("Closed %i\n"), fd); - OutputDebugStringW(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 deleted file mode 100644 index e34a8259d39..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/raise.c +++ /dev/null @@ -1,194 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2002, 2011 QNX Software Systems and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * QNX Software Systems - initial API and implementation - * - * raise.c - * - * This is a part of JNI implementation of spawner - *******************************************************************************/ -#include "stdafx.h" -#include "Spawner.h" - - -#include "jni.h" - -extern void JNICALL ThrowByName(JNIEnv *env, const char *name, const char *msg); - - -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) -{ - DWORD thread_id; - DWORD process_id; - DWORD pid = arg; - - thread_id = GetWindowThreadProcessId (hwnd, &process_id); - if (process_id == pid) - { - wchar_t window_class[32]; - - GetClassName (hwnd, window_class, sizeof (window_class)); - if (wcscmp (window_class, L"ConsoleWindowClass") == 0) - { - consoleHWND = hwnd; - return FALSE; - } - } - /* keep looking */ - return TRUE; -} - -// Need to declare this Win32 prototype ourselves. _WIN32_WINNT is getting -// defined to a Windows NT value, thus we don't get this. Can't assume -// we're running on XP, anyway (or can we by now?) -#if (_WIN32_WINNT < 0x0501) || defined(_MSC_VER) -typedef BOOL (WINAPI *DebugBreakProcessFunc)(HANDLE); -#endif - -///////////////////////////////////////////////////////////////////////////////////// -// Called to interrupt a process that we didn't launch (and thus does not share our -// console). Windows XP introduced the function 'DebugBreakProcess', which allows -// a process to interrupt another process even if if the two do not share a console. -// If we're running on 2000 or earlier, we have to resort to simulating a CTRL-C -// in the console by firing keyboard events. This will work only if the process -// has its own console. That means, e.g., the process should have been started at -// the cmdline with 'start myprogram.exe' instead of 'myprogram.exe'. -// -// Arguments: -// pid - process' pid -// Return : 0 if OK or error code -///////////////////////////////////////////////////////////////////////////////////// -int interruptProcess(int pid) -{ - // See if DebugBreakProcess is available (XP and beyond) - HMODULE hmod = LoadLibrary(L"Kernel32.dll"); - if (hmod != NULL) - { - BOOL success = FALSE; - FARPROC procaddr = GetProcAddress(hmod, "DebugBreakProcess"); - if (procaddr != NULL) - { - HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); - if (proc != NULL) - { - DebugBreakProcessFunc pDebugBreakProcess = (DebugBreakProcessFunc)procaddr; - success = (*pDebugBreakProcess)(proc); - CloseHandle(proc); - } - } - FreeLibrary(hmod); - hmod = NULL; - - if (success) - return 0; // 0 == OK; if not, try old-school way - } - -#ifdef DEBUG_MONITOR - _TCHAR buffer[1000]; -#endif - int rc = 0; - consoleHWND = NULL; - -#ifdef DEBUG_MONITOR - _stprintf(buffer, _T("Try to interrupt process %i\n"), pid); - OutputDebugStringW(buffer); -#endif - // Find console - EnumWindows (find_child_console, (LPARAM) pid); - - 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'; - BYTE vk_break_code = VK_CANCEL; - 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) - { - /* NT 5.0, and apparently also Windows 98, will not allow - a Window to be set to foreground directly without the - user's involvement. The workaround is to attach - ourselves to the thread that owns the foreground - window, since that is the only thread that can set the - foreground window. */ - DWORD foreground_thread, child_thread; - foreground_thread = - GetWindowThreadProcessId (foreground_window, NULL); - if (foreground_thread == GetCurrentThreadId () - || !AttachThreadInput (GetCurrentThreadId (), - foreground_thread, TRUE)) - foreground_thread = 0; - - child_thread = GetWindowThreadProcessId (consoleHWND, NULL); - if (child_thread == GetCurrentThreadId () - || !AttachThreadInput (GetCurrentThreadId (), - child_thread, TRUE)) - child_thread = 0; - - /* Set the foreground window to the child. */ - if (SetForegroundWindow (consoleHWND)) - { - if(0 != break_scan_code) { - /* Generate keystrokes as if user had typed Ctrl-Break */ - keybd_event (VK_CONTROL, control_scan_code, 0, 0); - keybd_event (vk_break_code, break_scan_code, KEYEVENTF_EXTENDEDKEY, 0); - keybd_event (vk_break_code, break_scan_code, - KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); - keybd_event (VK_CONTROL, control_scan_code, KEYEVENTF_KEYUP, 0); - } - - /* Sleep for a bit to give time for respond */ - Sleep (100); - - SetForegroundWindow (foreground_window); - } - /* Detach from the foreground and child threads now that - the foreground switching is over. */ - if (foreground_thread) - AttachThreadInput (GetCurrentThreadId (), - foreground_thread, FALSE); - if (child_thread) - AttachThreadInput (GetCurrentThreadId (), - child_thread, FALSE); -#ifdef DEBUG_MONITOR - _stprintf(buffer, _T("Sent Ctrl-C & Ctrl-Break to process %i\n"), pid); - OutputDebugStringW(buffer); -#endif - } - } -#ifdef DEBUG_MONITOR - else { - _stprintf(buffer, _T("Cannot find console for process %i\n"), pid); - OutputDebugStringW(buffer); - } -#endif - - return rc; -} - diff --git a/core/org.eclipse.cdt.core.win32/library/setenv64.bat b/core/org.eclipse.cdt.core.win32/library/setenv64.bat deleted file mode 100644 index dfe68b7394a..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/setenv64.bat +++ /dev/null @@ -1 +0,0 @@ -"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\setenv.cmd" /x64 /2003 /Release
\ No newline at end of file diff --git a/core/org.eclipse.cdt.core.win32/library/spawner.c b/core/org.eclipse.cdt.core.win32/library/spawner.c deleted file mode 100644 index c4d52bb8a41..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/spawner.c +++ /dev/null @@ -1,57 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2002, 2007 QNX Software Systems and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * QNX Software Systems - initial API and implementation - * - * spawner.c - * - * This is a part of JNI implementation of spawner - *******************************************************************************/ - -#include "stdafx.h" -#include "spawner.h" - - -CRITICAL_SECTION cs; - - -wchar_t path[MAX_PATH + 1] = {_T('\0') }; // Directory where spawner.dll is located - -extern "C" -BOOL APIENTRY DllMain( HINSTANCE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - { - wchar_t * p; - InitializeCriticalSection(&cs); - GetModuleFileNameW(hModule, path, MAX_PATH); - p = wcsrchr(path, _T('\\')); - if(NULL != p) - *(p + 1) = _T('\0'); - else - wcscat(path, L"\\"); - } - break; - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - break; - case DLL_PROCESS_DETACH: - DeleteCriticalSection(&cs); - break; - } - return TRUE; -} - diff --git a/core/org.eclipse.cdt.core.win32/library/starter/Makefile b/core/org.eclipse.cdt.core.win32/library/starter/Makefile deleted file mode 100644 index 54c92c5b829..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/starter/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -OS = win32 -ARCH = x86 - -TARGET = $(INSTALL_DIR)/starter.exe - -OBJS = starter.o - -LIBS = -lpsapi - -CXX = g++ -CXXFLAGS = -DUNICODE - -INSTALL_DIR = ../../../org.eclipse.cdt.core.$(OS).$(ARCH)/os/$(OS)/$(ARCH) - -all: $(TARGET) - -rebuild: clean all - -clean : - $(RM) $(OBJS) - -$(TARGET) : $(OBJS) - $(CXX) -o $(TARGET) $(OBJS) $(LIBS) diff --git a/core/org.eclipse.cdt.core.win32/library/starter/starter.cpp b/core/org.eclipse.cdt.core.win32/library/starter/starter.cpp deleted file mode 100644 index 30dfe2f078b..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/starter/starter.cpp +++ /dev/null @@ -1,526 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2002, 2015 QNX Software Systems and others. - * - * This program and the accompanying materials - * are made available under the terms of the Eclipse Public License 2.0 - * which accompanies this distribution, and is available at - * https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * QNX Software Systems - initial API and implementation - * Wind River Systems, Inc. - * - * starter.cpp - * - * This is a small utility for windows spawner - *******************************************************************************/ - -#define STRICT -#define _WIN32_WINNT 0x0500 -#include <windows.h> -#include <process.h> -#include <tchar.h> -#include <stdio.h> -#include <psapi.h> - -//#define DEBUG_MONITOR -#define MAX_CMD_LINE_LENGTH (2049) -#define PIPE_NAME_LENGTH 100 - -int copyTo(wchar_t * target, const wchar_t * source, int cpyLength, - int availSpace); -void DisplayErrorMessage(); - -//BOOL KillProcessEx(DWORD dwProcessId); // Handle of the process - -/////////////////////////////////////////////////////////////////////////////// -BOOL WINAPI HandlerRoutine( DWORD dwCtrlType) // control signal type -{ - BOOL ret = TRUE; - switch(dwCtrlType) - { - case CTRL_C_EVENT: - break; - case CTRL_BREAK_EVENT: - break; - case CTRL_CLOSE_EVENT: - ret = FALSE; - break; - case CTRL_LOGOFF_EVENT: - ret = FALSE; - break; - case CTRL_SHUTDOWN_EVENT: - ret = FALSE; - break; - default: - break; - } - return ret; -} - -// The default here means we haven't checked yet -// i.e. cygwin is true but the bin dir hasn't been captured -wchar_t * cygwinBin = NULL; -bool _isCygwin = true; - -bool isCygwin(HANDLE process) { - // Have we checked before? - if (cygwinBin != NULL || !_isCygwin) - return _isCygwin; - - // See if this process loaded cygwin, need a different SIGINT for them - HMODULE mods[1024]; - DWORD needed; - if (EnumProcessModules(process, mods, sizeof(mods), &needed)) { - int i; - needed /= sizeof(HMODULE); - for (i = 0; i < needed; ++i ) { - wchar_t modName[MAX_PATH]; - if (GetModuleFileNameEx(process, mods[i], modName, MAX_PATH)) { - wchar_t * p = wcsrchr(modName, L'\\'); - if (p) { - *p = 0; // Null terminate there for future reference - if (!wcscmp(++p, L"cygwin1.dll")) { - _isCygwin = true; - // Store away the bind dir - cygwinBin = wcsdup(modName); - return _isCygwin; - } - } - } - } - } - - _isCygwin = false; - return _isCygwin; -} - -bool runCygwinCommand(wchar_t * command) { - wchar_t cygcmd[1024]; - swprintf(cygcmd, L"%s\\%s", cygwinBin, command); - - STARTUPINFO si; - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - PROCESS_INFORMATION pi; - ZeroMemory(&pi, sizeof(pi)); - if (CreateProcess(NULL, cygcmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { - WaitForSingleObject(pi.hProcess, INFINITE); - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - return true; - } else if (CreateProcess(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { - WaitForSingleObject(pi.hProcess, INFINITE); - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); - return true; - } - return false; -} - -void ensureSize(wchar_t** ptr, int* psize, int requiredLength) { - int size= *psize; - if (requiredLength > size) { - size= 2*size; - if (size < requiredLength) { - size= requiredLength; - } - *ptr= (wchar_t *)realloc(*ptr, size * sizeof(wchar_t)); - if (NULL == *ptr) { - *psize= 0; - } else { - *psize= size; - } - } -} - -int main() { - - int argc; - wchar_t ** argv = CommandLineToArgvW(GetCommandLine(), &argc); - - // Make sure that we've been passed the right number of arguments - if (argc < 8) { - _tprintf(_T("Usage: %s (four inheritable event handles) (CommandLineToSpawn)\n"), - argv[0]); - return(0); - } - - // Construct the full command line - int nCmdLineLength= MAX_CMD_LINE_LENGTH; - wchar_t * szCmdLine= (wchar_t *)malloc(nCmdLineLength * sizeof(wchar_t)); - szCmdLine[0]= 0; - int nPos = 0; - - for(int i = 8; i < argc; ++i) - { - int nCpyLen; - int len= wcslen(argv[i]); - int requiredSize= nPos+len+2; - if (requiredSize > 32*1024) { -#ifdef DEBUG_MONITOR - OutputDebugStringW(_T("Command line too long!\n")); -#endif - return 0; - } - ensureSize(&szCmdLine, &nCmdLineLength, requiredSize); - if (NULL == szCmdLine) { -#ifdef DEBUG_MONITOR - OutputDebugStringW(_T("Not enough memory to build cmd line!\n")); -#endif - return 0; - } - if(0 > (nCpyLen = copyTo(szCmdLine + nPos, argv[i], len, nCmdLineLength - nPos))) - { -#ifdef DEBUG_MONITOR - OutputDebugStringW(_T("Not enough space to build command line\n")); -#endif - return 0; - } - nPos += nCpyLen; - szCmdLine[nPos] = _T(' '); - ++nPos; - } - szCmdLine[nPos] = _T('\0'); - - STARTUPINFOW si = {sizeof(si)}; - PROCESS_INFORMATION pi = {0}; - DWORD dwExitCode = 0; -#ifdef DEBUG_MONITOR - int currentPID = GetCurrentProcessId(); - wchar_t buffer[MAX_CMD_LINE_LENGTH]; -#endif - - BOOL exitProc = FALSE; - HANDLE waitEvent = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[4]); - HANDLE h[5]; - h[0] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[3]); // simulated SIGINT (CTRL-C or Cygwin 'kill -SIGINT') -// h[1] we reserve for the process handle - h[2] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[5]); // simulated SIGTERM - h[3] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[6]); // simulated SIGKILL - h[4] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[7]); // CTRL-C, in all cases - - SetConsoleCtrlHandler(HandlerRoutine, TRUE); - - int parentPid = wcstol(argv[1], NULL, 10); - int nCounter = wcstol(argv[2], NULL, 10); - wchar_t inPipeName[PIPE_NAME_LENGTH]; - wchar_t outPipeName[PIPE_NAME_LENGTH]; - wchar_t errPipeName[PIPE_NAME_LENGTH]; - - swprintf(inPipeName, L"\\\\.\\pipe\\stdin%08i%010i", parentPid, nCounter); - swprintf(outPipeName, L"\\\\.\\pipe\\stdout%08i%010i", parentPid, nCounter); - swprintf(errPipeName, L"\\\\.\\pipe\\stderr%08i%010i", parentPid, nCounter); -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("Pipes: %s, %s, %s\n"), inPipeName, outPipeName, errPipeName); - OutputDebugStringW(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] = CreateFileW(inPipeName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, &sa))) || - (INVALID_HANDLE_VALUE == (stdHandles[1] = CreateFileW(outPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa))) || - (INVALID_HANDLE_VALUE == (stdHandles[2] = CreateFileW(errPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa)))) - { -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("Failed to open pipe %i, %i, %i: %i\n"), stdHandles[0], stdHandles[1], stdHandles[2], GetLastError()); - OutputDebugStringW(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 - swprintf(buffer, _T("Failed to reassign standard streams: %i\n"), GetLastError()); - OutputDebugStringW(buffer); -#endif - CloseHandle(stdHandles[0]); - CloseHandle(stdHandles[1]); - CloseHandle(stdHandles[2]); - return -1;; - } - -#ifdef DEBUG_MONITOR_DETAILS - wchar_t * lpvEnv = GetEnvironmentStringsW(); - - // If the returned pointer is NULL, exit. - if (lpvEnv == NULL) - OutputDebugStringW(_T("Cannot Read Environment\n")); - else { - // Variable strings are separated by NULL byte, and the block is - // terminated by a NULL byte. - - OutputDebugStringW(_T("Starter: Environment\n")); - for (wchar_t * lpszVariable = (wchar_t *) lpvEnv; *lpszVariable; lpszVariable+=wcslen(lpszVariable) + 1) { - swprintf(buffer, _T("%s\n"), lpszVariable); - OutputDebugStringW(buffer); - } - - FreeEnvironmentStringsW(lpvEnv); - } -#endif -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("Starting: %s\n"), szCmdLine); - OutputDebugStringW(buffer); -#endif - // Create job object - HANDLE hJob = CreateJobObject(NULL, NULL); - if (hJob != NULL) { - // Configure job to - // - terminate all associated processes when the last handle to it is closed - // - allow child processes to break away from the job. - JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo; - ZeroMemory(&jobInfo, sizeof(jobInfo)); - jobInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_BREAKAWAY_OK; - if (!SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &jobInfo, sizeof(jobInfo))) { -#ifdef DEBUG_MONITOR - OutputDebugStringW(_T("Cannot set job information\n")); - DisplayErrorMessage(); -#endif - } - } else { -#ifdef DEBUG_MONITOR - OutputDebugStringW(_T("Cannot create job object\n")); - DisplayErrorMessage(); -#endif - } - // Spawn the other processes as part of this Process Group - // If this process is already part of a job, the flag CREATE_BREAKAWAY_FROM_JOB - // makes the child process detach from the job, such that we can assign it - // to our own job object. - BOOL f = CreateProcessW(NULL, szCmdLine, NULL, NULL, TRUE, - CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi); - // If breaking away from job is not permitted, retry without breakaway flag - if (!f) - f = CreateProcessW(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 - swprintf(buffer, _T("Process %i started\n"), pi.dwProcessId); - OutputDebugStringW(buffer); -#endif - SetEvent(waitEvent); // Means that process has been spawned - CloseHandle(pi.hThread); - h[1] = pi.hProcess; - - if(NULL != hJob) { - if(!AssignProcessToJobObject(hJob, pi.hProcess)) { -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("Cannot assign process %i to a job\n"), pi.dwProcessId); - OutputDebugStringW(buffer); - DisplayErrorMessage(); -#endif - } - } - - while(!exitProc) - { - // Wait for the spawned-process to die or for the event - // indicating that the processes should be forcibly killed. - DWORD event = WaitForMultipleObjects(5, h, FALSE, INFINITE); - switch (event) - { - case WAIT_OBJECT_0 + 0: // SIGINT - case WAIT_OBJECT_0 + 4: // CTRL-C -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("starter (PID %i) received CTRL-C event\n"), currentPID); - OutputDebugStringW(buffer); -#endif - if ((event == (WAIT_OBJECT_0 + 0)) && isCygwin(h[1])) { - // Need to issue a kill command - wchar_t kill[1024]; - swprintf(kill, L"kill -SIGINT %d", pi.dwProcessId); - if (!runCygwinCommand(kill)) { - // fall back to console event - GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); - } - } else { - GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); - } - - SetEvent(waitEvent); - break; - - case WAIT_OBJECT_0 + 1: // App terminated normally - // Make it's exit code our exit code -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("starter: launched process has been terminated(PID %i)\n"), - pi.dwProcessId); - OutputDebugStringW(buffer); -#endif - GetExitCodeProcess(pi.hProcess, &dwExitCode); - exitProc = TRUE; - break; - - // Terminate and Kill behavior differ only for cygwin processes, where - // we use the cygwin 'kill' command. We send a SIGKILL in one case, - // SIGTERM in the other. For non-cygwin processes, both requests - // are treated exactly the same - case WAIT_OBJECT_0 + 2: // TERM - case WAIT_OBJECT_0 + 3: // KILL - { - const wchar_t* signal = (event == WAIT_OBJECT_0 + 2) ? L"TERM" : L"KILL"; -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("starter received %s event (PID %i)\n"), signal, currentPID); - OutputDebugStringW(buffer); -#endif - if (isCygwin(h[1])) { - // Need to issue a kill command - wchar_t kill[1024]; - swprintf(kill, L"kill -%s %d", signal, pi.dwProcessId); - if (!runCygwinCommand(kill)) { - // fall back to console event - GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); - } - } else { - GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); - } - - SetEvent(waitEvent); - - if(NULL != hJob) { - if(!TerminateJobObject(hJob, (DWORD)-1)) { -#ifdef DEBUG_MONITOR - OutputDebugStringW(_T("Cannot terminate job\n")); - DisplayErrorMessage(); -#endif - } - } - - // Note that we keep trucking until the child process terminates (case WAIT_OBJECT_0 + 1) - break; - } - - default: - // Unexpected code -#ifdef DEBUG_MONITOR - DisplayErrorMessage(); -#endif - exitProc = TRUE; - break; - } - - } - } else { -#ifdef DEBUG_MONITOR - swprintf(buffer, _T("Cannot start: %s\n"), szCmdLine); - OutputDebugStringW(buffer); - - DisplayErrorMessage(); -#endif - } - - if (NULL != szCmdLine) - { - free(szCmdLine); - } - - CloseHandle(waitEvent); - CloseHandle(h[0]); - CloseHandle(h[1]); - CloseHandle(h[2]); - CloseHandle(h[3]); - CloseHandle(h[4]); - - return(dwExitCode); -} - -///////////////////////////////////////////////////////////////////////////////////// -// 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(wchar_t * target, const wchar_t * source, int cpyLength, - int availSpace) { - BOOL bSlash = FALSE; - int i = 0, j = 0; - int totCpyLength = cpyLength; - -#define QUOTATION_DO 0 -#define QUOTATION_DONE 1 -#define QUOTATION_NONE 2 - - int nQuotationMode = 0; - if (availSpace <= cpyLength) // = to reserve space for '\0' - return -1; - - if ((_T('\"') == *source) && (_T('\"') == *(source + cpyLength - 1))) { - // Already done - nQuotationMode = QUOTATION_DONE; - } else if (wcschr(source, _T(' '))== NULL) { - // No reason to quotate term becase it doesn't have embedded spaces - nQuotationMode = QUOTATION_NONE; - } else { - // Needs to be quotated - nQuotationMode = QUOTATION_DO; - *target = _T('\"'); - ++j; - } - - for (; i < cpyLength; ++i, ++j) { - if (source[i] == _T('\\')) - bSlash = TRUE; - else - // Don't escape embracing quotation marks - if ((source[i] == _T('\"')) && !((nQuotationMode == QUOTATION_DONE) && ((i == 0) || (i == (cpyLength - 1))) )) { - if (!bSlash) { - if (j == availSpace) - return -1; - target[j] = _T('\\'); - ++j; - } - bSlash = FALSE; - } else - bSlash = FALSE; - - if (j == availSpace) - return -1; - target[j] = source[i]; - } - - if (nQuotationMode == QUOTATION_DO) { - if (j == availSpace) - return -1; - target[j] = _T('\"'); - ++j; - } - return j; -} - -void DisplayErrorMessage() { - wchar_t * lpMsgBuf; - FormatMessageW( - FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (wchar_t *) &lpMsgBuf, 0, NULL); - OutputDebugStringW(lpMsgBuf); - // Free the buffer. - LocalFree(lpMsgBuf); -} - -//////////////////////////////// End of File ////////////////////////////////// |