diff --git a/core/org.eclipse.cdt.core.linux.aarch64/os/linux/aarch64/libspawner.so b/core/org.eclipse.cdt.core.linux.aarch64/os/linux/aarch64/libspawner.so index 386a513709a..f0d076d9ff6 100755 Binary files a/core/org.eclipse.cdt.core.linux.aarch64/os/linux/aarch64/libspawner.so and b/core/org.eclipse.cdt.core.linux.aarch64/os/linux/aarch64/libspawner.so differ diff --git a/core/org.eclipse.cdt.core.linux.x86_64/os/linux/x86_64/libspawner.so b/core/org.eclipse.cdt.core.linux.x86_64/os/linux/x86_64/libspawner.so index 656a9c8bb86..dddd4fbc72c 100755 Binary files a/core/org.eclipse.cdt.core.linux.x86_64/os/linux/x86_64/libspawner.so and b/core/org.eclipse.cdt.core.linux.x86_64/os/linux/x86_64/libspawner.so differ diff --git a/core/org.eclipse.cdt.core.macosx/os/macosx/x86/libspawner.jnilib b/core/org.eclipse.cdt.core.macosx/os/macosx/x86/libspawner.jnilib index b61cab931e0..99547975b6c 100755 Binary files a/core/org.eclipse.cdt.core.macosx/os/macosx/x86/libspawner.jnilib and b/core/org.eclipse.cdt.core.macosx/os/macosx/x86/libspawner.jnilib differ diff --git a/core/org.eclipse.cdt.core.macosx/os/macosx/x86_64/libspawner.jnilib b/core/org.eclipse.cdt.core.macosx/os/macosx/x86_64/libspawner.jnilib index 5761b5e5010..73c5622ac60 100755 Binary files a/core/org.eclipse.cdt.core.macosx/os/macosx/x86_64/libspawner.jnilib and b/core/org.eclipse.cdt.core.macosx/os/macosx/x86_64/libspawner.jnilib differ diff --git a/core/org.eclipse.cdt.core.native/native_src/include/Spawner.h b/core/org.eclipse.cdt.core.native/native_src/include/Spawner.h index 10750f2e202..2608be657dd 100644 --- a/core/org.eclipse.cdt.core.native/native_src/include/Spawner.h +++ b/core/org.eclipse.cdt.core.native/native_src/include/Spawner.h @@ -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 diff --git a/core/org.eclipse.cdt.core.native/native_src/include/SpawnerInputStream.h b/core/org.eclipse.cdt.core.native/native_src/include/SpawnerInputStream.h index 653c5659524..6ecf61b96a4 100644 --- a/core/org.eclipse.cdt.core.native/native_src/include/SpawnerInputStream.h +++ b/core/org.eclipse.cdt.core.native/native_src/include/SpawnerInputStream.h @@ -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 -/* 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 } diff --git a/core/org.eclipse.cdt.core.native/native_src/include/SpawnerOutputStream.h b/core/org.eclipse.cdt.core.native/native_src/include/SpawnerOutputStream.h index fb3e0354e88..5491f3f91c6 100644 --- a/core/org.eclipse.cdt.core.native/native_src/include/SpawnerOutputStream.h +++ b/core/org.eclipse.cdt.core.native/native_src/include/SpawnerOutputStream.h @@ -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 -/* 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 } diff --git a/core/org.eclipse.cdt.core.native/native_src/unix/io.c b/core/org.eclipse.cdt.core.native/native_src/unix/io.c index 94f03d63935..03dc08d4827 100644 --- a/core/org.eclipse.cdt.core.native/native_src/unix/io.c +++ b/core/org.eclipse.cdt.core.native/native_src/unix/io.c @@ -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); } diff --git a/core/org.eclipse.cdt.core.native/native_src/unix/spawner.c b/core/org.eclipse.cdt.core.native/native_src/unix/spawner.c index 623b1382cf8..3968e2a91c4 100644 --- a/core/org.eclipse.cdt.core.native/native_src/unix/spawner.c +++ b/core/org.eclipse.cdt.core.native/native_src/unix/spawner.c @@ -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, "", "(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, "", "(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); diff --git a/core/org.eclipse.cdt.core.native/native_src/win/Win32ProcessEx.c b/core/org.eclipse.cdt.core.native/native_src/win/Win32ProcessEx.c index 7b6bcc13699..433c06f1174 100644 --- a/core/org.eclipse.cdt.core.native/native_src/win/Win32ProcessEx.c +++ b/core/org.eclipse.cdt.core.native/native_src/win/Win32ProcessEx.c @@ -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, "", "(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 diff --git a/core/org.eclipse.cdt.core.native/native_src/win/iostream.c b/core/org.eclipse.cdt.core.native/native_src/win/iostream.c index 7fcfaf90d18..19aca37ccb5 100644 --- a/core/org.eclipse.cdt.core.native/native_src/win/iostream.c +++ b/core/org.eclipse.cdt.core.native/native_src/win/iostream.c @@ -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); diff --git a/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/pty/PTY.java b/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/pty/PTY.java index a92f5a06ace..4080fa25b8c 100644 --- a/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/pty/PTY.java +++ b/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/pty/PTY.java @@ -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; /** diff --git a/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/spawner/Spawner.java b/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/spawner/Spawner.java index c5249b99cb0..ee16552777f 100644 --- a/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/spawner/Spawner.java +++ b/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/spawner/Spawner.java @@ -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); } diff --git a/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/spawner/SpawnerInputStream.java b/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/spawner/SpawnerInputStream.java index 5e8e2926cc1..27533cc5fda 100644 --- a/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/spawner/SpawnerInputStream.java +++ b/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/spawner/SpawnerInputStream.java @@ -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$ diff --git a/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/spawner/SpawnerOutputStream.java b/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/spawner/SpawnerOutputStream.java index 01863b491f0..a6e51e824da 100644 --- a/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/spawner/SpawnerOutputStream.java +++ b/core/org.eclipse.cdt.core.native/src/org/eclipse/cdt/utils/spawner/SpawnerOutputStream.java @@ -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$ diff --git a/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/spawner.dll b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/spawner.dll index 710097dfc91..179f3b1c88a 100755 Binary files a/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/spawner.dll and b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/spawner.dll differ diff --git a/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/starter.exe b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/starter.exe index 69598bb22fb..26fffc7f53a 100755 Binary files a/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/starter.exe and b/core/org.eclipse.cdt.core.win32.x86_64/os/win32/x86_64/starter.exe differ