From 71be97ba3e284a4b481022e4cc0f2e6ce8f764f7 Mon Sep 17 00:00:00 2001 From: David Inglis Date: Wed, 17 Nov 2004 19:33:39 +0000 Subject: [PATCH] new pty supprt for spawner --- .../library/pty/PTY.h | 7 +- .../library/pty/pty.c | 2 +- .../library/spawner/Spawner.h | 20 ++- .../library/spawner/spawner.c | 123 +++++++++++++++++- .../os/qnx/x86/libpty.so | Bin 7028 -> 5412 bytes .../os/qnx/x86/libspawner.so | Bin 9426 -> 9840 bytes 6 files changed, 141 insertions(+), 11 deletions(-) diff --git a/core/org.eclipse.cdt.core.qnx/library/pty/PTY.h b/core/org.eclipse.cdt.core.qnx/library/pty/PTY.h index fabf58152d0..46a8dd9b622 100644 --- a/core/org.eclipse.cdt.core.qnx/library/pty/PTY.h +++ b/core/org.eclipse.cdt.core.qnx/library/pty/PTY.h @@ -7,12 +7,13 @@ #ifdef __cplusplus extern "C" { #endif +/* Inaccessible static: hasPTY */ /* * Class: org_eclipse_cdt_utils_pty_PTY - * Method: forkpty - * Signature: ()I + * Method: openMaster + * Signature: ()Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_forkpty +JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_openMaster (JNIEnv *, jobject); #ifdef __cplusplus diff --git a/core/org.eclipse.cdt.core.qnx/library/pty/pty.c b/core/org.eclipse.cdt.core.qnx/library/pty/pty.c index 4b9e682c3ee..1ff87e17c7f 100644 --- a/core/org.eclipse.cdt.core.qnx/library/pty/pty.c +++ b/core/org.eclipse.cdt.core.qnx/library/pty/pty.c @@ -7,7 +7,7 @@ * Signature: ()I */ JNIEXPORT jstring JNICALL -Java_org_eclipse_cdt_utils_pty_PTY_forkpty (JNIEnv *env, jobject jobj) { +Java_org_eclipse_cdt_utils_pty_PTY_openMaster (JNIEnv *env, jobject jobj) { jfieldID fid; /* Store the field ID */ jstring jstr = NULL; int master = -1; diff --git a/core/org.eclipse.cdt.core.qnx/library/spawner/Spawner.h b/core/org.eclipse.cdt.core.qnx/library/spawner/Spawner.h index 287c8370ab0..272366bad75 100644 --- a/core/org.eclipse.cdt.core.qnx/library/spawner/Spawner.h +++ b/core/org.eclipse.cdt.core.qnx/library/spawner/Spawner.h @@ -1,9 +1,9 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ #include -/* Header for class com_qnx_tools_utils_spawner_Spawner */ +/* Header for class org_eclipse_cdt_utils_spawner_Spawner */ -#ifndef _Included_com_qnx_tools_utils_spawner_Spawner -#define _Included_com_qnx_tools_utils_spawner_Spawner +#ifndef _Included_org_eclipse_cdt_utils_spawner_Spawner +#define _Included_org_eclipse_cdt_utils_spawner_Spawner #ifdef __cplusplus extern "C" { #endif @@ -17,12 +17,20 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0 /* * Class: org_eclipse_cdt_utils_spawner_Spawner - * Method: exec0 - * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[I)I + * 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;[ILjava/lang/String;I)I + */ +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2 + (JNIEnv *, jobject, jobjectArray, jobjectArray, jstring, jintArray, jstring, jint); + /* * Class: org_eclipse_cdt_utils_spawner_Spawner * Method: raise diff --git a/core/org.eclipse.cdt.core.qnx/library/spawner/spawner.c b/core/org.eclipse.cdt.core.qnx/library/spawner/spawner.c index a6c1cef581f..c6d638f7ab1 100644 --- a/core/org.eclipse.cdt.core.qnx/library/spawner/spawner.c +++ b/core/org.eclipse.cdt.core.qnx/library/spawner/spawner.c @@ -205,6 +205,127 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1 } +JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec2 + (JNIEnv * env, jobject proc, jobjectArray cmdArray, jobjectArray envp, jstring dir, jintArray channels, jstring jslave, jint master) +{ + 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 cwd[PATH_MAX + 1]; /* Current working directory. */ + pid_t pid; /* Process ID. */ + struct inheritance inherit; + + if ((cmdArray == NULL) || ((nParms = (*env)->GetArrayLength(env, cmdArray)) == 0)) { + ThrowByName(env, "java/lang/IOException", "No command line specified"); + } + + { + char *pts_name = (char *)(*env)->GetStringUTFChars(env, jslave, 0); + int fds = ptys_open(master, pts_name); + (*env)->ReleaseStringUTFChars(env, jslave, pts_name); + if (fds == -1) { + ThrowByName(env, "java/io/IOException", "Cannot create pipe for spawner"); + } + if (EOK != pipe(fd)) { + ThrowByName(env, "java/io/IOException", "Cannot create pipe for spawner"); + } + fd_map[0] = fd_map[1] = fds; + fd_map[2] = fd[1]; + fd_ret[0] = fd_ret[1] = master; + fd_ret[3] = 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 = (char *)(*env)->GetStringUTFChars(env, dir, 0); + getcwd(cwd, sizeof(cwd)); + chdir(item); + (*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); + } + + /* Free Parameters. */ + if (pParms != NULL) { + int j; + for (j = 0; pParms[j] != NULL; j++) { + if (pParms[j] != NULL) { + free(pParms[j]); + } + } + free(pParms); + } + + /* Free Environment variables. */ + if (pEnvs != NULL) { + int j; + for (j = 0; pEnvs[j] != NULL; j++) { + if (pEnvs[j] != NULL) { + free(pEnvs[j]); + } + } + free(pEnvs); + } + + /* Free Command to execute. */ + if (pCommand != NULL) { + free(pCommand); + } + + return pid; + +} + /* * Class: com_qnx_tools_utils_spawner_Spawner * Method: raise @@ -224,7 +345,7 @@ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor (JNIEnv * env, jobject proc, jint pid) { - int ret; + int ret, stat_loc; int val = -1; ret = waitpid(pid, &stat_loc, WEXITED); diff --git a/core/org.eclipse.cdt.core.qnx/os/qnx/x86/libpty.so b/core/org.eclipse.cdt.core.qnx/os/qnx/x86/libpty.so index 6af6b21e775a75d0e9069b2e9dcd5434ae26fb2d..7e8be555ff2d834538b6200ab36bc8f64272b6ad 100644 GIT binary patch literal 5412 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 literal 7028 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 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 index 8744bb15a6c0ba8a15c605104030e4b8edba76c8..61f6c9d9ef6b62f1d30bbcc8170d5a49893524f0 100644 GIT binary patch literal 9840 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 literal 9426 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 Y=hAU(h7$u}$*VBe1ULNvv_xS47pwqH9RL6T