From cf15b1fb76bf209fa0002dcf35f1a2795afc7c24 Mon Sep 17 00:00:00 2001 From: David Inglis Date: Tue, 3 Sep 2002 16:16:58 +0000 Subject: [PATCH] qnx spawner --- core/org.eclipse.cdt.core.qnx/.classpath | 15 ++ core/org.eclipse.cdt.core.qnx/.project | 38 +++ .../org.eclipse.cdt.core.qnx/build.properties | 2 + core/org.eclipse.cdt.core.qnx/fragment.xml | 20 ++ .../org.eclipse.cdt.core.qnx/library/Makefile | 8 + .../library/Spawner.h | 45 ++++ .../library/SpawnerInputStream.h | 32 +++ .../library/SpawnerOutputStream.h | 29 ++ .../library/common.mk | 14 + .../library/iostream.c | 109 ++++++++ .../library/spawner.c | 252 ++++++++++++++++++ .../library/x86/Makefile | 8 + .../library/x86/so/Makefile | 1 + .../os/qnx/x86/libspawner.so | 0 14 files changed, 573 insertions(+) create mode 100644 core/org.eclipse.cdt.core.qnx/.classpath create mode 100644 core/org.eclipse.cdt.core.qnx/.project create mode 100644 core/org.eclipse.cdt.core.qnx/build.properties create mode 100644 core/org.eclipse.cdt.core.qnx/fragment.xml create mode 100644 core/org.eclipse.cdt.core.qnx/library/Makefile create mode 100644 core/org.eclipse.cdt.core.qnx/library/Spawner.h create mode 100644 core/org.eclipse.cdt.core.qnx/library/SpawnerInputStream.h create mode 100644 core/org.eclipse.cdt.core.qnx/library/SpawnerOutputStream.h create mode 100644 core/org.eclipse.cdt.core.qnx/library/common.mk create mode 100644 core/org.eclipse.cdt.core.qnx/library/iostream.c create mode 100644 core/org.eclipse.cdt.core.qnx/library/spawner.c create mode 100644 core/org.eclipse.cdt.core.qnx/library/x86/Makefile create mode 100644 core/org.eclipse.cdt.core.qnx/library/x86/so/Makefile create mode 100644 core/org.eclipse.cdt.core.qnx/os/qnx/x86/libspawner.so diff --git a/core/org.eclipse.cdt.core.qnx/.classpath b/core/org.eclipse.cdt.core.qnx/.classpath new file mode 100644 index 00000000000..782d615590a --- /dev/null +++ b/core/org.eclipse.cdt.core.qnx/.classpath @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.core.qnx/.project b/core/org.eclipse.cdt.core.qnx/.project new file mode 100644 index 00000000000..09ef1e466c8 --- /dev/null +++ b/core/org.eclipse.cdt.core.qnx/.project @@ -0,0 +1,38 @@ + + + org.eclipse.cdt.core.qnx + + + org.apache.xerces + org.eclipse.cdt.core + org.eclipse.compare + org.eclipse.core.boot + org.eclipse.core.resources + org.eclipse.core.runtime + org.eclipse.debug.core + org.eclipse.debug.ui + org.eclipse.search + org.eclipse.ui + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/core/org.eclipse.cdt.core.qnx/build.properties b/core/org.eclipse.cdt.core.qnx/build.properties new file mode 100644 index 00000000000..99f473dc81f --- /dev/null +++ b/core/org.eclipse.cdt.core.qnx/build.properties @@ -0,0 +1,2 @@ +bin.includes = fragment.xml,\ + os/ diff --git a/core/org.eclipse.cdt.core.qnx/fragment.xml b/core/org.eclipse.cdt.core.qnx/fragment.xml new file mode 100644 index 00000000000..3feddab9410 --- /dev/null +++ b/core/org.eclipse.cdt.core.qnx/fragment.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.core.qnx/library/Makefile b/core/org.eclipse.cdt.core.qnx/library/Makefile new file mode 100644 index 00000000000..959e9b2292f --- /dev/null +++ b/core/org.eclipse.cdt.core.qnx/library/Makefile @@ -0,0 +1,8 @@ +LIST=CPU +ifndef QRECURSE +QRECURSE=recurse.mk +ifdef QCONFIG +QRDIR=$(dir $(QCONFIG)) +endif +endif +include $(QRDIR)$(QRECURSE) diff --git a/core/org.eclipse.cdt.core.qnx/library/Spawner.h b/core/org.eclipse.cdt.core.qnx/library/Spawner.h new file mode 100644 index 00000000000..01ffb3cc1b2 --- /dev/null +++ b/core/org.eclipse.cdt.core.qnx/library/Spawner.h @@ -0,0 +1,45 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_qnx_tools_utils_spawner_Spawner */ + +#ifndef _Included_com_qnx_tools_utils_spawner_Spawner +#define _Included_com_qnx_tools_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: exec0 + * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[I)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: 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); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/org.eclipse.cdt.core.qnx/library/SpawnerInputStream.h b/core/org.eclipse.cdt.core.qnx/library/SpawnerInputStream.h new file mode 100644 index 00000000000..3b32d2b2806 --- /dev/null +++ b/core/org.eclipse.cdt.core.qnx/library/SpawnerInputStream.h @@ -0,0 +1,32 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* 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: org_elipse_cdt_utils_spawner_SpawnerInputStream + * Method: read0 + * Signature: (I[BI)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_read0 + (JNIEnv *, jobject, jint, jbyteArray, jint); + +/* + * Class: org_eclipse_cdt_utils_spawner_SpawnerInputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0 + (JNIEnv *, jobject, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/org.eclipse.cdt.core.qnx/library/SpawnerOutputStream.h b/core/org.eclipse.cdt.core.qnx/library/SpawnerOutputStream.h new file mode 100644 index 00000000000..f835947e060 --- /dev/null +++ b/core/org.eclipse.cdt.core.qnx/library/SpawnerOutputStream.h @@ -0,0 +1,29 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* 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: org_eclipse_cdt_utils_spawner_SpawnerOutputStream + * Method: write0 + * Signature: (I[BI)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_write0 + (JNIEnv *, jobject, jint, jbyteArray, jint); + +/* + * Class: org_eclipse_cdt_utils_spawner_SpawnerOutputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0 + (JNIEnv *, jobject, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/org.eclipse.cdt.core.qnx/library/common.mk b/core/org.eclipse.cdt.core.qnx/library/common.mk new file mode 100644 index 00000000000..c903556f9ec --- /dev/null +++ b/core/org.eclipse.cdt.core.qnx/library/common.mk @@ -0,0 +1,14 @@ +ifndef QCONFIG +QCONFIG=qconfig.mk +endif +include $(QCONFIG) + +include $(MKFILES_ROOT)/qtargets.mk + +ifeq ($(OS),nto) +ifeq ($(IVEHOME),) +IVEHOME:=/opt/vame/ive +endif +EXTRA_INCVPATH+=$(IVEHOME)/bin/include +endif + diff --git a/core/org.eclipse.cdt.core.qnx/library/iostream.c b/core/org.eclipse.cdt.core.qnx/library/iostream.c new file mode 100644 index 00000000000..e947522b48e --- /dev/null +++ b/core/org.eclipse.cdt.core.qnx/library/iostream.c @@ -0,0 +1,109 @@ +/* Copyright, 2002, QNX Software Systems Ltd. All Rights Reserved + + * This source code has been published by QNX Software Systems + * Ltd. (QSSL). However, any use, reproduction, modification, distribution + * or transfer of this software, or any software which includes or is based + * upon any of this code, is only permitted if expressly authorized by a + * written license agreement from QSSL. Contact the QNX Developer's Network + * or contact QSSL's legal department for more information. + * + * + * iostream.c + * + * This is a JNI implementation of access to standard i/o streams + */ +#include +#include +#include +#include +#include + +#include "SpawnerInputStream.h" +#include "SpawnerOutputStream.h" + + +#include "jni.h" + + +void ThrowByName(JNIEnv *env, const char *name, const char *msg); + +#define BUFF_SIZE (1024) + +/* Inaccessible static: skipBuffer */ +/* + * Class: SpawnerInputStream + * Method: read0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_read0 + (JNIEnv * env, jobject proc, jint fd, jbyteArray buf, jint len) +{ + unsigned char tmpBuf[BUFF_SIZE]; + int nBuffOffset = 0; +// printf("Come to read0\n"); + while(len > nBuffOffset) + { + int nReadLen = min(len - nBuffOffset, BUFF_SIZE); + int nread; + nread = read(fd, tmpBuf, nReadLen); + if(nread > 0) + (*env) -> SetByteArrayRegion(env, buf, nBuffOffset, nReadLen, tmpBuf); + else + break; + nBuffOffset += nread; + if(nread != nReadLen) + break; + } +// printf("Leave read with %i bytes read\n", nBuffOffset); + return nBuffOffset; // This is a real full readed length + +} + +/* + * Class: SpawnerInputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0 + (JNIEnv * env, jobject proc, jint fd) +{ + return close(fd); +} + +/* + * Class: SpawnerOutputStream + * Method: write0 + * Signature: (I[BI)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_write0 + (JNIEnv * env, jobject proc, jint fd, jbyteArray buf, jint len) +{ + unsigned char tmpBuf[BUFF_SIZE]; + int nBuffOffset = 0; +// int rc = 0; +// printf("Come to write0, len = %i\n", len); + while(len > nBuffOffset) + { + int nWriteLen = min(len - nBuffOffset, BUFF_SIZE); + (*env) -> GetByteArrayRegion(env, buf, nBuffOffset, nWriteLen, tmpBuf); +// printf("Write %i bytes; last byte = %#x\n", nWriteLen, (int)tmpBuf[nWriteLen - 1]); + if(nWriteLen != write(fd, tmpBuf, nWriteLen)) + { +// printf("Error: written %i bytes; errno = %i, fd = %i, len = %i ", nWriteLen, errno, fd, rc); + ThrowByName(env, "java/io/IOException", strerror(errno)); + } + nBuffOffset += nWriteLen; + } + return 0; +} + +/* + * Class: SpawnerOutputStream + * Method: close0 + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0 + (JNIEnv * env, jobject proc, jint fd) +{ + return close(fd); +} diff --git a/core/org.eclipse.cdt.core.qnx/library/spawner.c b/core/org.eclipse.cdt.core.qnx/library/spawner.c new file mode 100644 index 00000000000..85c0515eedc --- /dev/null +++ b/core/org.eclipse.cdt.core.qnx/library/spawner.c @@ -0,0 +1,252 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Spawner.h" + +typedef JNIEXPORT void * (JNICALL * JVM_GetThreadInterruptEvent)(); +typedef JNIEXPORT char * (JNICALL * JVM_NativePath)(const char *); + +void ThrowByName(JNIEnv *env, const char *name, const char *msg); +void * GetJVMProc(char * vmlib, char * procName); + + +static void * hVM = NULL; // Java Virtual Machine handler + + +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0 + (JNIEnv * env, jobject proc, jobjectArray cmdArray, jobjectArray envp, jstring dir, jintArray channels) +{ + int fd_map[3]; // File descriptors + int fd_ret[3]; // File descriptors that we return to Java + int fd[2]; // Pipe open structure + int i; + int nParms = 0;// Number of parameters + int nEnvs = 0;// Number of environment variables + char ** pParms = NULL; // Parameters + char ** pEnvs = NULL; // Environment variables + char * pCommand = NULL; // Command to execute + char * pwd = 0; // Process working directory + char cwd[PATH_MAX + 1]; // Current working directory + pid_t pid; // Process ID + struct inheritance inherit; + + + + if ((cmdArray == 0) || ((nParms = (*env) -> GetArrayLength(env, cmdArray)) == 0)) + ThrowByName(env, "java/lang/NullPointerException", "No command line specified"); + for(i = 0; i < 3; ++i) + { + if(EOK != pipe(fd)) + ThrowByName(env, "java/io/IOException", "Cannot create pipe for spawner"); + if(0 ==i) + { + fd_map[i] = fd[0]; + fd_ret[i] = fd[1]; + } + else + { + fd_map[i] = fd[1]; + fd_ret[i] = fd[0]; + } + } + + + + if(nParms > 0) + { + pParms = malloc(sizeof(char *) * (nParms + 1)); + for(i = 0; i < nParms; ++i) + { + jobject item = (*env) -> GetObjectArrayElement(env, cmdArray, i); + const char * str = (*env) -> GetStringUTFChars(env, item, 0); + if(i == 0) + pCommand = strdup(str); + pParms[i] = strdup(str); + (*env) -> ReleaseStringUTFChars(env, item, str); + } + pParms[i] = NULL; + } + nEnvs = (*env) -> GetArrayLength(env, envp); + if(nEnvs > 0) + { + pEnvs = malloc(sizeof(char *) * (nEnvs + 1)); + for(i = 0; i < nEnvs; ++i) + { + jobject item = (*env) -> GetObjectArrayElement(env, envp, i); + const char * str = (*env) -> GetStringUTFChars(env, item, 0); + pEnvs[i] = strdup(str); + (*env) -> ReleaseStringUTFChars(env, item, str); + } + pEnvs[i] = NULL; + } + + if (dir != 0) + { + char * item; + pwd = strdup(item = (char *)(*env) -> GetStringUTFChars(env, dir, 0)); + getcwd(cwd, sizeof(cwd)); + chdir(pwd); + (*env) -> ReleaseStringUTFChars(env, dir, item); + } + + // Nothing for now + memset(&inherit, 0, sizeof(inherit)); + inherit.flags = SPAWN_SETGROUP; + inherit.pgroup = SPAWN_NEWPGROUP; + + pid = spawnp(pCommand, 3, fd_map, &inherit, pParms, pEnvs); + + if(dir != 0) // Restore working directory + chdir(cwd); + + for(i = 0; i < 3; ++i) + { + close(fd_map[i]); + } + + if(-1 == pid) // Failed - close pipes + { + for(i = 0; i < 3; ++i) + { + close(fd_ret[i]); + } + } + else // Success - return pipes to Java + { + (*env) -> SetIntArrayRegion(env, channels, 0, 3, fd_ret); + } + + return pid; + +} + +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1 + (JNIEnv * env, jobject proc, jobjectArray cmdArray, jobjectArray envp, jstring dir) +{ + int i; + int nParms = 0;// Number of parameters + int nEnvs = 0;// Number of environment variables + char ** pParms = NULL; // Parameters + char ** pEnvs = NULL; // Environment variables + char * pCommand = NULL; // Command to execute + char * pwd = 0; // Process working directory + char cwd[PATH_MAX + 1]; // Current working directory + pid_t pid; // Process ID + struct inheritance inherit; + + + if ((cmdArray == 0) || ((nParms = (*env) -> GetArrayLength(env, cmdArray)) == 0)) + ThrowByName(env, "java/lang/NullPointerException", "No command line specified"); + + + if(nParms > 0) + { + pParms = malloc(sizeof(char *) * (nParms + 1)); + for(i = 0; i < nParms; ++i) + { + jobject item = (*env) -> GetObjectArrayElement(env, cmdArray, i); + const char * str = (*env) -> GetStringUTFChars(env, item, 0); + if(i == 0) + pCommand = strdup(str); + pParms[i] = strdup(str); + (*env) -> ReleaseStringUTFChars(env, item, str); + } + pParms[i] = NULL; + } + nEnvs = (*env) -> GetArrayLength(env, envp); + if(nEnvs > 0) + { + pEnvs = malloc(sizeof(char *) * (nEnvs + 1)); + for(i = 0; i < nEnvs; ++i) + { + jobject item = (*env) -> GetObjectArrayElement(env, envp, i); + const char * str = (*env) -> GetStringUTFChars(env, item, 0); + pEnvs[i] = strdup(str); + (*env) -> ReleaseStringUTFChars(env, item, str); + } + pEnvs[i] = NULL; + } + + if (dir != 0) + { + char * item; + pwd = strdup(item = (char *)(*env) -> GetStringUTFChars(env, dir, 0)); + getcwd(cwd, sizeof(cwd)); + chdir(pwd); + (*env) -> ReleaseStringUTFChars(env, dir, item); + } + + // Nothing for now + memset(&inherit, 0, sizeof(inherit)); + inherit.flags = SPAWN_SETGROUP; + inherit.pgroup = SPAWN_NEWPGROUP; + + + pid = spawnp(pCommand, 0, NULL, &inherit, pParms, pEnvs); + + + if(dir != 0) // Restore working directory + chdir(cwd); + + return pid; + +} + +/* + * Class: com_qnx_tools_utils_spawner_Spawner + * Method: raise + * Signature: (II)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise + (JNIEnv * env, jobject proc, jint pid, jint sig) +{ + return kill(pid, sig); +} + +/* + * Class: com_qnx_tools_utils_spawner_Spawner + * Method: waitFor + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor + (JNIEnv * env, jobject proc, jint pid) +{ + int stat_loc; + return (waitpid(pid, &stat_loc, WEXITED)); +} + + +// Utilities + +void ThrowByName(JNIEnv *env, const char *name, const char *msg) +{ + jclass cls = (*env)->FindClass(env, name); + + if (cls != 0) /* Otherwise an exception has already been thrown */ + (*env)->ThrowNew(env, cls, msg); + + /* It's a good practice to clean up the local references. */ + (*env)->DeleteLocalRef(env, cls); +} + + + +void * GetJVMProc(char * vmlib, char * procName) +{ + if(NULL == vmlib) + vmlib = "libj9vm14.so"; + if((NULL == hVM) || (NULL == procName)) + { + if(NULL == (hVM = dlopen(vmlib, 0))) + return NULL; + } + return dlsym(hVM, procName); +} diff --git a/core/org.eclipse.cdt.core.qnx/library/x86/Makefile b/core/org.eclipse.cdt.core.qnx/library/x86/Makefile new file mode 100644 index 00000000000..6a18617612e --- /dev/null +++ b/core/org.eclipse.cdt.core.qnx/library/x86/Makefile @@ -0,0 +1,8 @@ +LIST=VARIANT +ifndef QRECURSE +QRECURSE=recurse.mk +ifdef QCONFIG +QRDIR=$(dir $(QCONFIG)) +endif +endif +include $(QRDIR)$(QRECURSE) diff --git a/core/org.eclipse.cdt.core.qnx/library/x86/so/Makefile b/core/org.eclipse.cdt.core.qnx/library/x86/so/Makefile new file mode 100644 index 00000000000..9d6821f4c2a --- /dev/null +++ b/core/org.eclipse.cdt.core.qnx/library/x86/so/Makefile @@ -0,0 +1 @@ +include ../../../common.mk diff --git a/core/org.eclipse.cdt.core.qnx/os/qnx/x86/libspawner.so b/core/org.eclipse.cdt.core.qnx/os/qnx/x86/libspawner.so new file mode 100644 index 00000000000..e69de29bb2d