/******************************************************************************* * Copyright (c) 2002, 2010 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * QNX Software Systems - initial API and implementation * Wind River Systems, Inc. * Mikhail Zabaluev (Nokia) - bug 82744 *******************************************************************************/ #include #include #include #include #include #include #include "exec0.h" #include #define DEBUGIT 0 /* * Header for class org_eclipse_cdt_utils_spawner_Spawner */ #if DEBUGIT static void print_array(char **c_array) { if (c_array) { char **p = c_array; for (; *p; p++) { if (*p) { fprintf(stderr, " %s", *p); } } } else { fprintf(stderr, "null"); } fprintf(stderr, "\n"); } #endif static char **alloc_c_array(JNIEnv * env, jobjectArray j_array) { int i; jint c_array_size = (*env)->GetArrayLength(env, j_array); char **c_array = calloc(c_array_size + 1, sizeof(*c_array)); if (c_array == NULL) return NULL; for (i = 0; i < c_array_size; i++) { jstring j_str = (jstring) (*env)->GetObjectArrayElement(env, j_array, i); const char *c_str = (*env)->GetStringUTFChars(env, j_str, NULL); c_array[i] = (char *) strdup(c_str); (*env)->ReleaseStringUTFChars(env, j_str, c_str); (*env)->DeleteLocalRef(env, j_str); } return c_array; } static void free_c_array(char **c_array) { if (c_array) { char **p = c_array; for (; *p; p++) { if (*p) { free(*p); } } free(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, 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; char **envp = NULL; int fd[3]; pid_t pid = -1; if (channels == NULL) goto bail_out; cmd = alloc_c_array(env, jcmd); if (cmd == NULL) goto bail_out; envp = alloc_c_array(env, jenv); if (envp == NULL) goto bail_out; #if DEBUGIT fprintf(stderr, "command:"); print_array(cmd); fprintf(stderr, "Envp:"); print_array(envp); fprintf(stderr, "dirpath: %s\n", dirpath); fprintf(stderr, "pts_name: %s\n", pts_name); #endif pid = exec_pty(cmd[0], cmd, envp, dirpath, fd, pts_name, masterFD, console); if (pid < 0) goto bail_out; channels[0] = fd[0]; channels[1] = fd[1]; channels[2] = fd[2]; bail_out: (*env)->ReleaseIntArrayElements(env, jchannels, channels, 0); (*env)->ReleaseStringUTFChars(env, jdir, dirpath); (*env)->ReleaseStringUTFChars(env, jslaveName, pts_name); if (cmd) free_c_array(cmd); if (envp) free_c_array(envp); return pid; } JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1(JNIEnv * env, jobject jobj, jobjectArray jcmd, jobjectArray jenv, jstring jdir) { const char *dirpath = (*env)->GetStringUTFChars(env, jdir, NULL); char **cmd = NULL; char **envp = NULL; pid_t pid = -1; cmd = alloc_c_array(env, jcmd); if (cmd == NULL) goto bail_out; envp = alloc_c_array(env, jenv); if (envp == NULL) goto bail_out; #if DEBUGIT fprintf(stderr, "command:"); print_array(cmd); fprintf(stderr, "Envp:"); print_array(envp); fprintf(stderr, "dirpath: %s\n", dirpath); #endif pid = exec0(cmd[0], cmd, envp, dirpath, NULL); if (pid < 0) goto bail_out; bail_out: (*env)->ReleaseStringUTFChars(env, jdir, dirpath); if (cmd) free_c_array(cmd); if (envp) free_c_array(envp); 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) { 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; if (channels == NULL) goto bail_out; cmd = alloc_c_array(env, jcmd); if (cmd == NULL) goto bail_out; envp = alloc_c_array(env, jenv); if (envp == NULL) goto bail_out; #if DEBUGIT fprintf(stderr, "command:"); print_array(cmd); fprintf(stderr, "Envp:"); 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]; bail_out: (*env)->ReleaseIntArrayElements(env, jchannels, channels, 0); (*env)->ReleaseStringUTFChars(env, jdir, dirpath); if (cmd) free_c_array(cmd); if (envp) free_c_array(envp); return pid; } /* * Class: org_eclipse_cdt_utils_spawner_Spawner * Method: raise * Signature: (II)I */ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_raise(JNIEnv * env, jobject jobj, jint pid, jint sig) { int status = -1; switch (sig) { case 0: /* NOOP */ status = killpg(pid, 0); if(status == -1) { status = kill(pid, 0); } break; case 2: /* INTERRUPT */ status = killpg(pid, SIGINT); if(status == -1) { status = kill(pid, SIGINT); } break; case 9: /* KILL */ status = killpg(pid, SIGKILL); if(status == -1) { status = kill(pid, SIGKILL); } break; case 15: /* TERM */ status = killpg(pid, SIGTERM); if(status == -1) { status = kill(pid, SIGTERM); } break; default: status = killpg(pid, sig); /* WHAT ?? */ if(status == -1) { status = kill(pid, sig); /* WHAT ?? */ } break; } return status; } /* * Class: org_eclipse_cdt_utils_spawner_Spawner * Method: waitFor * Signature: (I)I */ JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_waitFor(JNIEnv * env, jobject jobj, jint pid) { return wait0(pid); }