mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
Bug 521515: Use channel object for native stream access
On Linux and mac, a simple int will do for accessing streams (file descriptor). On Windows, a HANDLE is used. This is in reality a pointer and on 64 bit JVM, the pointer will not fit in an int. To not force a change to the API everytime a different platform has a different requirement for accessing streams, use a common interface and specific classes that is known by the native part. The java part of the function block should just pass the object back to the native code when needing to reference an open stream. Change-Id: Ibc3ff5c85735dac6a0ce8e9a1f25b839d7e9aab9 Signed-off-by: Torbjörn Svensson <azoff@svenskalinuxforeningen.se>
This commit is contained in:
parent
0d50385e63
commit
49dc726dd1
17 changed files with 235 additions and 157 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002, 2010 QNX Software Systems and others.
|
||||
* Copyright (c) 2002, 2020 QNX Software Systems and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -27,10 +27,10 @@ extern "C" {
|
|||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||
* Method: exec0
|
||||
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[I)I
|
||||
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Lorg/eclipse/cdt/utils/spawner/Spawner/IChannel;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
||||
(JNIEnv *, jobject, jobjectArray, jobjectArray, jstring, jintArray);
|
||||
(JNIEnv *, jobject, jobjectArray, jobjectArray, jstring, jobjectArray);
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||
|
@ -43,10 +43,10 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
|
|||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||
* Method: exec2
|
||||
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[ILjava/lang/String;IZ)I
|
||||
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Lorg/eclipse/cdt/utils/spawner/Spawner/IChannel;Ljava/lang/String;IZ)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2
|
||||
(JNIEnv *, jobject, jobjectArray, jobjectArray, jstring, jintArray, jstring, jint, jboolean);
|
||||
(JNIEnv *, jobject, jobjectArray, jobjectArray, jstring, jobjectArray, jstring, jint, jboolean);
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||
|
@ -64,15 +64,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise
|
|||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
// #define DEBUG_MONITOR
|
||||
|
||||
int interruptProcess(int pid);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// #define DEBUG_MONITOR
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002, 2007 QNX Software Systems and others.
|
||||
* Copyright (c) 2002, 2020 QNX Software Systems and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -15,34 +15,40 @@
|
|||
*
|
||||
* 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 */
|
||||
/* Header for class org_eclipse_cdt_utils_spawner_SpawnerInputStream */
|
||||
|
||||
#ifndef _Included_com_qnx_tools_utils_spawner_SpawnerInputStream
|
||||
#define _Included_com_qnx_tools_utils_spawner_SpawnerInputStream
|
||||
#ifndef _Included_org_eclipse_cdt_utils_spawner_SpawnerInputStream
|
||||
#define _Included_org_eclipse_cdt_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 */
|
||||
#undef org_eclipse_cdt_utils_spawner_SpawnerInputStream_MAX_SKIP_BUFFER_SIZE
|
||||
#define org_eclipse_cdt_utils_spawner_SpawnerInputStream_MAX_SKIP_BUFFER_SIZE 2048L
|
||||
/*
|
||||
* Class: org_elipse_cdt_utils_spawner_SpawnerInputStream
|
||||
* Class: org_eclipse_cdt_utils_spawner_SpawnerInputStream
|
||||
* Method: read0
|
||||
* Signature: (I[BI)I
|
||||
* Signature: (Lorg/eclipse/cdt/utils/spawner/Spawner/IChannel;[BI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_read0
|
||||
(JNIEnv *, jobject, jint, jbyteArray, jint);
|
||||
(JNIEnv *, jobject, jobject, jbyteArray, jint);
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_SpawnerInputStream
|
||||
* Method: close0
|
||||
* Signature: (I)I
|
||||
* Signature: (Lorg/eclipse/cdt/utils/spawner/Spawner/IChannel;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0
|
||||
(JNIEnv *, jobject, jint);
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_SpawnerInputStream
|
||||
* Method: available0
|
||||
* Signature: (Lorg/eclipse/cdt/utils/spawner/Spawner/IChannel;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_available0
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002, 2007 QNX Software Systems and others.
|
||||
* Copyright (c) 2002, 2020 QNX Software Systems and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -17,28 +17,28 @@
|
|||
*******************************************************************************/
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class com_qnx_tools_utils_spawner_SpawnerOutputStream */
|
||||
/* Header for class org_eclipse_cdt_utils_spawner_SpawnerOutputStream */
|
||||
|
||||
#ifndef _Included_com_qnx_tools_utils_spawner_SpawnerOutputStream
|
||||
#define _Included_com_qnx_tools_utils_spawner_SpawnerOutputStream
|
||||
#ifndef _Included_org_eclipse_cdt_utils_spawner_SpawnerOutputStream
|
||||
#define _Included_org_eclipse_cdt_utils_spawner_SpawnerOutputStream
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_SpawnerOutputStream
|
||||
* Method: write0
|
||||
* Signature: (I[BI)I
|
||||
* Signature: (Lorg/eclipse/cdt/utils/spawner/Spawner/IChannel;[BI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_write0
|
||||
(JNIEnv *, jobject, jint, jbyteArray, jint);
|
||||
(JNIEnv *, jobject, jobject, jbyteArray, jint);
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_SpawnerOutputStream
|
||||
* Method: close0
|
||||
* Signature: (I)I
|
||||
* Signature: (Lorg/eclipse/cdt/utils/spawner/Spawner/IChannel;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0
|
||||
(JNIEnv *, jobject, jint);
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -21,15 +21,44 @@
|
|||
/* Header for class _org_eclipse_cdt_utils_spawner_SpawnerInputStream */
|
||||
/* Header for class _org_eclipse_cdt_utils_spawner_SpawnerOutputStream */
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_SpawnerInputStream
|
||||
* Method: read0
|
||||
* Signature: (I)I
|
||||
*/
|
||||
static 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);
|
||||
}
|
||||
|
||||
static int channelToFileDesc(JNIEnv * env, jobject channel)
|
||||
{
|
||||
if (channel == 0) {
|
||||
ThrowByName(env, "java/io/IOException", "Invalid channel object");
|
||||
return -1;
|
||||
}
|
||||
|
||||
jclass cls = (*env)->GetObjectClass(env, channel);
|
||||
if (cls == 0) {
|
||||
ThrowByName(env, "java/io/IOException", "Unable to get channel class");
|
||||
return -1;
|
||||
}
|
||||
|
||||
jfieldID fid = (*env)->GetFieldID(env, cls, "fd", "I");
|
||||
if (fid == 0) {
|
||||
ThrowByName(env, "java/io/IOException", "Unable to find fd");
|
||||
return -1;
|
||||
}
|
||||
|
||||
jint fd = (*env)->GetIntField(env, channel, fid);
|
||||
return fd;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_read0(JNIEnv * env,
|
||||
jobject jobj,
|
||||
jint jfd,
|
||||
jobject channel,
|
||||
jbyteArray buf,
|
||||
jint buf_len)
|
||||
{
|
||||
|
@ -40,7 +69,7 @@ Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_read0(JNIEnv * env,
|
|||
|
||||
data = (*env)->GetByteArrayElements(env, buf, 0);
|
||||
data_len = buf_len;
|
||||
fd = jfd;
|
||||
fd = channelToFileDesc(env, channel);
|
||||
|
||||
status = read( fd, data, data_len );
|
||||
(*env)->ReleaseByteArrayElements(env, buf, data, 0);
|
||||
|
@ -62,28 +91,19 @@ Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_read0(JNIEnv * env,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_SpawnerInputStream
|
||||
* Method: close0
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0(JNIEnv * env,
|
||||
jobject jobj,
|
||||
jint fd)
|
||||
jobject channel)
|
||||
{
|
||||
int fd = channelToFileDesc(env, channel);
|
||||
return close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_SpawnerOutputStream
|
||||
* Method: write0
|
||||
* Signature: (II)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_write0(JNIEnv * env,
|
||||
jobject jobj,
|
||||
jint jfd,
|
||||
jobject channel,
|
||||
jbyteArray buf,
|
||||
jint buf_len)
|
||||
{
|
||||
|
@ -94,7 +114,7 @@ Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_write0(JNIEnv * env,
|
|||
|
||||
data = (*env)->GetByteArrayElements(env, buf, 0);
|
||||
data_len = buf_len;
|
||||
fd = jfd;
|
||||
fd = channelToFileDesc(env, channel);
|
||||
|
||||
status = write(fd, data, data_len);
|
||||
(*env)->ReleaseByteArrayElements(env, buf, data, 0);
|
||||
|
@ -103,15 +123,11 @@ Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_write0(JNIEnv * env,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_SpawnerOutputStream
|
||||
* Method: close0
|
||||
* Signature: (I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0(JNIEnv * env,
|
||||
jobject jobj,
|
||||
jint fd)
|
||||
jobject channel)
|
||||
{
|
||||
int fd = channelToFileDesc(env, channel);
|
||||
return close(fd);
|
||||
}
|
||||
|
|
|
@ -86,16 +86,10 @@ static void free_c_array(char **c_array)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: org_eclipse_cdt_utils_spawner_Spawner
|
||||
* Method: exec2
|
||||
* Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[ILorg/eclipse/cdt/utils/pty/PTY;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2
|
||||
(JNIEnv *env, jobject jobj, jobjectArray jcmd, jobjectArray jenv, jstring jdir, jintArray jchannels,
|
||||
(JNIEnv *env, jobject jobj, jobjectArray jcmd, jobjectArray jenv, jstring jdir, jobjectArray jchannels,
|
||||
jstring jslaveName, jint masterFD, jboolean console)
|
||||
{
|
||||
jint *channels = (*env)->GetIntArrayElements(env, jchannels, 0);
|
||||
const char *dirpath = (*env)->GetStringUTFChars(env, jdir, NULL);
|
||||
const char *pts_name = (*env)->GetStringUTFChars(env, jslaveName, NULL);
|
||||
char **cmd = NULL;
|
||||
|
@ -103,7 +97,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2
|
|||
int fd[3];
|
||||
pid_t pid = -1;
|
||||
|
||||
if (channels == NULL)
|
||||
if (jchannels == NULL)
|
||||
goto bail_out;
|
||||
|
||||
cmd = alloc_c_array(env, jcmd);
|
||||
|
@ -127,12 +121,15 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2
|
|||
if (pid < 0)
|
||||
goto bail_out;
|
||||
|
||||
channels[0] = fd[0];
|
||||
channels[1] = fd[1];
|
||||
channels[2] = fd[2];
|
||||
jobject cls = (*env)->FindClass(env, "org/eclipse/cdt/utils/spawner/Spawner$UnixChannel");
|
||||
jmethodID constructor = (*env)->GetMethodID(env, cls, "<init>", "(I)V");
|
||||
for (jsize i = 0; i < 3; i++) {
|
||||
jobject chan = (*env)->NewObject(env, cls, constructor, fd[i]);
|
||||
(*env)->SetObjectArrayElement(env, jchannels, i, chan);
|
||||
}
|
||||
|
||||
|
||||
bail_out:
|
||||
(*env)->ReleaseIntArrayElements(env, jchannels, channels, 0);
|
||||
(*env)->ReleaseStringUTFChars(env, jdir, dirpath);
|
||||
(*env)->ReleaseStringUTFChars(env, jslaveName, pts_name);
|
||||
if (cmd)
|
||||
|
@ -183,26 +180,30 @@ Java_org_eclipse_cdt_utils_spawner_Spawner_exec1(JNIEnv * env, jobject jobj,
|
|||
return pid;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 * env, jobject jobj,
|
||||
jobjectArray jcmd,
|
||||
jobjectArray jenv,
|
||||
jstring jdir,
|
||||
jintArray jchannels)
|
||||
jobjectArray jchannels)
|
||||
{
|
||||
jint *channels = (*env)->GetIntArrayElements(env, jchannels, 0);
|
||||
const char *dirpath = (*env)->GetStringUTFChars(env, jdir, NULL);
|
||||
char **cmd = NULL;
|
||||
char **envp = NULL;
|
||||
int fd[3];
|
||||
pid_t pid = -1;
|
||||
jclass channelClass = NULL;
|
||||
jmethodID channelConstructor = NULL;
|
||||
|
||||
if (channels == NULL)
|
||||
if (jchannels == NULL)
|
||||
goto bail_out;
|
||||
|
||||
channelClass = (*env)->FindClass(env, "org/eclipse/cdt/utils/spawner/Spawner$UnixChannel");
|
||||
if (channelClass == 0)
|
||||
goto bail_out;
|
||||
|
||||
channelConstructor = (*env)->GetMethodID(env, channelClass, "<init>", "(I)V");
|
||||
if (channelConstructor == 0)
|
||||
goto bail_out;
|
||||
|
||||
cmd = alloc_c_array(env, jcmd);
|
||||
|
@ -220,17 +221,16 @@ Java_org_eclipse_cdt_utils_spawner_Spawner_exec0(JNIEnv * env, jobject jobj,
|
|||
print_array(envp);
|
||||
fprintf(stderr, "dirpath: %s\n", dirpath);
|
||||
#endif
|
||||
|
||||
pid = exec0(cmd[0], cmd, envp, dirpath, fd);
|
||||
if (pid < 0)
|
||||
goto bail_out;
|
||||
|
||||
channels[0] = fd[0];
|
||||
channels[1] = fd[1];
|
||||
channels[2] = fd[2];
|
||||
for (jsize i = 0; i < 3; i++) {
|
||||
jobject chan = (*env)->NewObject(env, channelClass, channelConstructor, fd[i]);
|
||||
(*env)->SetObjectArrayElement(env, jchannels, i, chan);
|
||||
}
|
||||
|
||||
bail_out:
|
||||
(*env)->ReleaseIntArrayElements(env, jchannels, channels, 0);
|
||||
(*env)->ReleaseStringUTFChars(env, jdir, dirpath);
|
||||
if (cmd)
|
||||
free_c_array(cmd);
|
||||
|
|
|
@ -70,6 +70,8 @@ static int copyTo(wchar_t * target, const wchar_t * source, int cpyLenght, int
|
|||
// Use this function to clean project descriptor and return it to the pool of available blocks.
|
||||
static void cleanUpProcBlock(pProcInfo_t pCurProcInfo);
|
||||
|
||||
int interruptProcess(int pid);
|
||||
|
||||
|
||||
// Signal codes
|
||||
typedef enum {
|
||||
|
@ -106,7 +108,7 @@ static int nCounter = 0; // We use it to build unique synchronization object nam
|
|||
extern "C"
|
||||
#endif
|
||||
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)
|
||||
(JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir, jobjectArray channels, jstring slaveName, jint fdm, jboolean console)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
@ -133,7 +135,7 @@ void ensureSize(wchar_t** ptr, int* psize, int requiredLength)
|
|||
extern "C"
|
||||
#endif
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
||||
(JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir, jintArray channels)
|
||||
(JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir, jobjectArray channels)
|
||||
{
|
||||
HANDLE stdHandles[3];
|
||||
PROCESS_INFORMATION pi = {0}, *piCopy;
|
||||
|
@ -169,6 +171,28 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
|||
wchar_t inPipeName[PIPE_NAME_LENGTH];
|
||||
wchar_t outPipeName[PIPE_NAME_LENGTH];
|
||||
wchar_t errPipeName[PIPE_NAME_LENGTH];
|
||||
jclass channelClass = NULL;
|
||||
jmethodID channelConstructor = NULL;
|
||||
|
||||
if (channels == NULL)
|
||||
{
|
||||
ThrowByName(env, "java/io/IOException", "Channels can't be null");
|
||||
return 0;
|
||||
}
|
||||
|
||||
channelClass = (*env)->FindClass(env, "org/eclipse/cdt/utils/spawner/Spawner$WinChannel");
|
||||
if (channelClass == 0)
|
||||
{
|
||||
ThrowByName(env, "java/io/IOException", "Unable to find channel class");
|
||||
return 0;
|
||||
}
|
||||
|
||||
channelConstructor = (*env)->GetMethodID(env, channelClass, "<init>", "(J)V");
|
||||
if (channelConstructor == 0)
|
||||
{
|
||||
ThrowByName(env, "java/io/IOException", "Unable to find channel constructor");
|
||||
return 0;
|
||||
}
|
||||
|
||||
nCmdLineLength= MAX_CMD_SIZE;
|
||||
szCmdLine= (wchar_t *)malloc(nCmdLineLength * sizeof(wchar_t));
|
||||
|
@ -406,7 +430,6 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
|||
}
|
||||
else
|
||||
{
|
||||
int file_handles[3];
|
||||
HANDLE h[2];
|
||||
int what;
|
||||
|
||||
|
@ -434,10 +457,10 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
|
|||
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(env, channels, 0, 3, (jint *)file_handles);
|
||||
for (jsize i = 0; i < 3; i++) {
|
||||
jobject chan = (*env)->NewObject(env, channelClass, channelConstructor, (jlong)stdHandles[i]);
|
||||
(*env)->SetObjectArrayElement(env, channels, i, chan);
|
||||
}
|
||||
|
||||
// do the cleanup so launch the according thread
|
||||
// create a copy of the PROCESS_INFORMATION as this might get destroyed
|
||||
|
|
|
@ -29,20 +29,39 @@ void ThrowByName(JNIEnv *env, const char *name, const char *msg);
|
|||
|
||||
#define BUFF_SIZE (1024)
|
||||
|
||||
static HANDLE channelToHandle(JNIEnv * env, jobject channel)
|
||||
{
|
||||
if (channel == 0) {
|
||||
ThrowByName(env, "java/io/IOException", "Invalid channel object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jclass cls = (*env)->GetObjectClass(env, channel);
|
||||
if (cls == NULL) {
|
||||
ThrowByName(env, "java/io/IOException", "Unable to get channel class");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jfieldID fid = (*env)->GetFieldID(env, cls, "handle", "J");
|
||||
if (fid == NULL) {
|
||||
ThrowByName(env, "java/io/IOException", "Unable to find handle");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jlong handle = (*env)->GetLongField(env, channel, fid);
|
||||
return (HANDLE)handle;
|
||||
}
|
||||
|
||||
/* Inaccessible static: skipBuffer */
|
||||
/*
|
||||
* Class: SpawnerInputStream
|
||||
* Method: read0
|
||||
* Signature: (I)I
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_read0
|
||||
(JNIEnv * env, jobject proc, jint fd, jbyteArray buf, jint len)
|
||||
(JNIEnv * env, jobject proc, jobject channel, jbyteArray buf, jint len)
|
||||
{
|
||||
jbyte tmpBuf[BUFF_SIZE];
|
||||
int nBuffOffset = 0;
|
||||
HANDLE handle = channelToHandle(env, channel);
|
||||
#ifdef DEBUG_MONITOR
|
||||
_TCHAR buffer[1000];
|
||||
#endif
|
||||
|
@ -84,7 +103,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
|
|||
{
|
||||
DWORD nNumberOfBytesToRead = min(len - nBuffOffset, BUFF_SIZE);
|
||||
DWORD nNumberOfBytesRead;
|
||||
if(0 == ReadFile((HANDLE)fd, tmpBuf, nNumberOfBytesToRead, &nNumberOfBytesRead, &overlapped ))
|
||||
if(0 == ReadFile(handle, tmpBuf, nNumberOfBytesToRead, &nNumberOfBytesRead, &overlapped ))
|
||||
{
|
||||
int err = GetLastError();
|
||||
|
||||
|
@ -92,7 +111,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
|
|||
{
|
||||
// asynchronous i/o is still in progress
|
||||
// check on the results of the asynchronous read
|
||||
if(GetOverlappedResult((HANDLE)fd, &overlapped,
|
||||
if(GetOverlappedResult(handle, &overlapped,
|
||||
&nNumberOfBytesRead, TRUE))
|
||||
err = 0;
|
||||
// if there was a problem ...
|
||||
|
@ -151,7 +170,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
|
|||
{
|
||||
// Is there data left in the pipe?
|
||||
DWORD bytesAvailable = 0;
|
||||
if (!PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &bytesAvailable, NULL)
|
||||
if (!PeekNamedPipe(handle, NULL, 0, NULL, &bytesAvailable, NULL)
|
||||
|| bytesAvailable == 0)
|
||||
// No bytes left
|
||||
break;
|
||||
|
@ -168,24 +187,20 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_rea
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: SpawnerInputStream
|
||||
* Method: close0
|
||||
* Signature: (I)I
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_close0
|
||||
(JNIEnv * env, jobject proc, jint fd)
|
||||
(JNIEnv * env, jobject proc, jobject channel)
|
||||
{
|
||||
int rc;
|
||||
HANDLE handle = channelToHandle(env, channel);
|
||||
#ifdef DEBUG_MONITOR
|
||||
_TCHAR buffer[1000];
|
||||
_stprintf(buffer, _T("Close %i\n"), fd);
|
||||
OutputDebugStringW(buffer);
|
||||
#endif
|
||||
rc = (CloseHandle((HANDLE)fd) ? 0 : -1);
|
||||
rc = (CloseHandle(handle) ? 0 : -1);
|
||||
#ifdef DEBUG_MONITOR
|
||||
_stprintf(buffer, _T("Closed %i\n"), fd);
|
||||
OutputDebugStringW(buffer);
|
||||
|
@ -197,38 +212,34 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_clo
|
|||
extern "C"
|
||||
#endif
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerInputStream_available0
|
||||
(JNIEnv * env, jobject proc, jint fd)
|
||||
(JNIEnv * env, jobject proc, jobject channel)
|
||||
{
|
||||
DWORD nAvail = 0;
|
||||
HANDLE handle = channelToHandle(env, channel);
|
||||
|
||||
if (0 == PeekNamedPipe((HANDLE)fd, NULL, 0, NULL, &nAvail, NULL)) {
|
||||
if (0 == PeekNamedPipe(handle, NULL, 0, NULL, &nAvail, NULL)) {
|
||||
// error
|
||||
return 0;
|
||||
}
|
||||
return nAvail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: SpawnerOutputStream
|
||||
* Method: write0
|
||||
* Signature: (I[BI)I
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_write0
|
||||
(JNIEnv * env, jobject proc, jint fd, jbyteArray buf, jint len)
|
||||
(JNIEnv * env, jobject proc, jobject channel, jbyteArray buf, jint len)
|
||||
{
|
||||
jbyte tmpBuf[BUFF_SIZE];
|
||||
int nBuffOffset = 0;
|
||||
|
||||
HANDLE handle = channelToHandle(env, channel);
|
||||
|
||||
while(len > nBuffOffset)
|
||||
{
|
||||
DWORD nNumberOfBytesToWrite = min(len - nBuffOffset, BUFF_SIZE);
|
||||
DWORD nNumberOfBytesWritten;
|
||||
(*env)->GetByteArrayRegion(env, buf, nBuffOffset, nNumberOfBytesToWrite, tmpBuf);
|
||||
if(0 == WriteFile((HANDLE)fd, tmpBuf, nNumberOfBytesToWrite, &nNumberOfBytesWritten, NULL))
|
||||
if(0 == WriteFile(handle, tmpBuf, nNumberOfBytesToWrite, &nNumberOfBytesWritten, NULL))
|
||||
{
|
||||
char * lpMsgBuf;
|
||||
FormatMessage(
|
||||
|
@ -252,25 +263,21 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_wr
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: SpawnerOutputStream
|
||||
* Method: close0
|
||||
* Signature: (I)I
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_SpawnerOutputStream_close0
|
||||
(JNIEnv * env, jobject proc, jint fd)
|
||||
(JNIEnv * env, jobject proc, jobject channel)
|
||||
{
|
||||
int rc;
|
||||
HANDLE handle = channelToHandle(env, channel);
|
||||
#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);
|
||||
FlushFileBuffers(handle);
|
||||
rc = (CloseHandle(handle) ? 0 : -1);
|
||||
#ifdef DEBUG_MONITOR
|
||||
_stprintf(buffer, _T("Closed %i\n"), fd);
|
||||
OutputDebugStringW(buffer);
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
|||
import org.eclipse.cdt.internal.core.natives.CNativePlugin;
|
||||
import org.eclipse.cdt.internal.core.natives.Messages;
|
||||
import org.eclipse.cdt.utils.spawner.Spawner;
|
||||
import org.eclipse.cdt.utils.spawner.Spawner.IChannel;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
|
||||
/**
|
||||
|
@ -223,7 +224,8 @@ public class PTY {
|
|||
* @noreference This method is not intended to be referenced by clients.
|
||||
* @since 5.6
|
||||
*/
|
||||
public int exec_pty(Spawner spawner, String[] cmdarray, String[] envp, String dir, int[] chan) throws IOException {
|
||||
public int exec_pty(Spawner spawner, String[] cmdarray, String[] envp, String dir, IChannel[] chan)
|
||||
throws IOException {
|
||||
if (isWinPTY) {
|
||||
return exec2(cmdarray, envp, dir, chan, slave, master, console);
|
||||
} else {
|
||||
|
@ -250,7 +252,7 @@ public class PTY {
|
|||
/**
|
||||
* Native method when executing with a terminal emulation (winpty only).
|
||||
*/
|
||||
native int exec2(String[] cmdarray, String[] envp, String dir, int[] chan, String slaveName, int masterFD,
|
||||
native int exec2(String[] cmdarray, String[] envp, String dir, IChannel[] chan, String slaveName, int masterFD,
|
||||
boolean console) throws IOException;
|
||||
|
||||
/**
|
||||
|
|
|
@ -65,7 +65,7 @@ public class Spawner extends Process {
|
|||
|
||||
int pid = 0;
|
||||
int status;
|
||||
final int[] fChannels = { -1, -1, -1 };
|
||||
final IChannel[] fChannels = { null, null, null };
|
||||
boolean isDone;
|
||||
OutputStream out;
|
||||
InputStream in;
|
||||
|
@ -363,7 +363,7 @@ public class Spawner extends Process {
|
|||
|
||||
Reaper reaper = new Reaper(cmdarray, envp, dirpath) {
|
||||
@Override
|
||||
int execute(String[] cmd, String[] env, String dir, int[] channels) throws IOException {
|
||||
int execute(String[] cmd, String[] env, String dir, IChannel[] channels) throws IOException {
|
||||
return pty.exec_pty(Spawner.this, cmd, env, dir, channels);
|
||||
}
|
||||
|
||||
|
@ -429,7 +429,7 @@ public class Spawner extends Process {
|
|||
/**
|
||||
* Native method use in normal exec() calls.
|
||||
*/
|
||||
native int exec0(String[] cmdarray, String[] envp, String dir, int[] chan) throws IOException;
|
||||
native int exec0(String[] cmdarray, String[] envp, String dir, IChannel[] chan) throws IOException;
|
||||
|
||||
/**
|
||||
* Native method use in no redirect meaning to streams will created.
|
||||
|
@ -440,8 +440,8 @@ public class Spawner extends Process {
|
|||
* Native method when executing with a terminal emulation.
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
*/
|
||||
public native int exec2(String[] cmdarray, String[] envp, String dir, int[] chan, String slaveName, int masterFD,
|
||||
boolean console) throws IOException;
|
||||
public native int exec2(String[] cmdarray, String[] envp, String dir, IChannel[] chan, String slaveName,
|
||||
int masterFD, boolean console) throws IOException;
|
||||
|
||||
/**
|
||||
* Native method to drop a signal on the process with pid.
|
||||
|
@ -464,6 +464,34 @@ public class Spawner extends Process {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 6.0
|
||||
*/
|
||||
public static interface IChannel {
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 6.0
|
||||
*/
|
||||
public static class WinChannel implements IChannel {
|
||||
final long handle;
|
||||
|
||||
public WinChannel(long handle) {
|
||||
this.handle = handle;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 6.0
|
||||
*/
|
||||
public static class UnixChannel implements IChannel {
|
||||
final int fd;
|
||||
|
||||
public UnixChannel(int fd) {
|
||||
this.fd = fd;
|
||||
}
|
||||
}
|
||||
|
||||
// Spawn a thread to handle the forking and waiting
|
||||
// We do it this way because on linux the SIGCHLD is
|
||||
// send to the one thread. So do the forking and
|
||||
|
@ -482,7 +510,7 @@ public class Spawner extends Process {
|
|||
fException = null;
|
||||
}
|
||||
|
||||
int execute(String[] cmdarray, String[] envp, String dir, int[] channels) throws IOException {
|
||||
int execute(String[] cmdarray, String[] envp, String dir, IChannel[] channels) throws IOException {
|
||||
return exec0(cmdarray, envp, dir, channels);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,16 +18,17 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
|
||||
import org.eclipse.cdt.internal.core.natives.Messages;
|
||||
import org.eclipse.cdt.utils.spawner.Spawner.IChannel;
|
||||
|
||||
class SpawnerInputStream extends InputStream {
|
||||
private int fd;
|
||||
private IChannel channel;
|
||||
|
||||
/**
|
||||
* From a Unix valid file descriptor set a Reader.
|
||||
* @param fd file descriptor.
|
||||
*/
|
||||
public SpawnerInputStream(int fd) {
|
||||
this.fd = fd;
|
||||
public SpawnerInputStream(IChannel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,7 +49,7 @@ class SpawnerInputStream extends InputStream {
|
|||
*/
|
||||
@Override
|
||||
public int read(byte[] buf, int off, int len) throws IOException {
|
||||
if (fd == -1) {
|
||||
if (channel == null) {
|
||||
return -1;
|
||||
}
|
||||
if (buf == null) {
|
||||
|
@ -60,7 +61,7 @@ class SpawnerInputStream extends InputStream {
|
|||
}
|
||||
byte[] tmpBuf = off > 0 ? new byte[len] : buf;
|
||||
|
||||
len = read0(fd, tmpBuf, len);
|
||||
len = read0(channel, tmpBuf, len);
|
||||
if (len <= 0)
|
||||
return -1;
|
||||
|
||||
|
@ -76,21 +77,21 @@ class SpawnerInputStream extends InputStream {
|
|||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (fd == -1)
|
||||
if (channel == null)
|
||||
return;
|
||||
int status = close0(fd);
|
||||
int status = close0(channel);
|
||||
if (status == -1)
|
||||
throw new IOException(Messages.Util_exception_closeError);
|
||||
fd = -1;
|
||||
channel = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
if (fd == -1) {
|
||||
if (channel == null) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
return available0(fd);
|
||||
return available0(channel);
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
// for those platforms that do not implement available0
|
||||
return super.available();
|
||||
|
@ -102,11 +103,11 @@ class SpawnerInputStream extends InputStream {
|
|||
close();
|
||||
}
|
||||
|
||||
private native int read0(int fileDesc, byte[] buf, int len) throws IOException;
|
||||
private native int read0(IChannel channel, byte[] buf, int len) throws IOException;
|
||||
|
||||
private native int close0(int fileDesc) throws IOException;
|
||||
private native int close0(IChannel channel) throws IOException;
|
||||
|
||||
private native int available0(int fileDesc) throws IOException;
|
||||
private native int available0(IChannel channel) throws IOException;
|
||||
|
||||
static {
|
||||
System.loadLibrary("spawner"); //$NON-NLS-1$
|
||||
|
|
|
@ -16,19 +16,22 @@ package org.eclipse.cdt.utils.spawner;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.eclipse.cdt.utils.spawner.Spawner.IChannel;
|
||||
|
||||
/**
|
||||
* @noextend This class is not intended to be subclassed by clients.
|
||||
* @noinstantiate This class is not intended to be instantiated by clients.
|
||||
*/
|
||||
public class SpawnerOutputStream extends OutputStream {
|
||||
private int fd;
|
||||
private IChannel channel;
|
||||
|
||||
/**
|
||||
* From a Unix valid file descriptor set a Reader.
|
||||
* @param fd file descriptor.
|
||||
* @param channel file descriptor.
|
||||
* @since 6.0
|
||||
*/
|
||||
public SpawnerOutputStream(int fd) {
|
||||
this.fd = fd;
|
||||
public SpawnerOutputStream(IChannel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,7 +48,7 @@ public class SpawnerOutputStream extends OutputStream {
|
|||
}
|
||||
byte[] tmpBuf = new byte[len];
|
||||
System.arraycopy(b, off, tmpBuf, off, len);
|
||||
write0(fd, tmpBuf, len);
|
||||
write0(channel, tmpBuf, len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,12 +69,12 @@ public class SpawnerOutputStream extends OutputStream {
|
|||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (fd == -1)
|
||||
if (channel == null)
|
||||
return;
|
||||
int status = close0(fd);
|
||||
int status = close0(channel);
|
||||
if (status == -1)
|
||||
throw new IOException("close error"); //$NON-NLS-1$
|
||||
fd = -1;
|
||||
channel = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -79,9 +82,9 @@ public class SpawnerOutputStream extends OutputStream {
|
|||
close();
|
||||
}
|
||||
|
||||
private native int write0(int fd, byte[] b, int len) throws IOException;
|
||||
private native int write0(IChannel channel, byte[] b, int len) throws IOException;
|
||||
|
||||
private native int close0(int fd);
|
||||
private native int close0(IChannel channel);
|
||||
|
||||
static {
|
||||
System.loadLibrary("spawner"); //$NON-NLS-1$
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Add table
Reference in a new issue