Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'core/org.eclipse.cdt.core.linux/library/spawner.c')
-rw-r--r--core/org.eclipse.cdt.core.linux/library/spawner.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/core/org.eclipse.cdt.core.linux/library/spawner.c b/core/org.eclipse.cdt.core.linux/library/spawner.c
new file mode 100644
index 00000000000..de2a9f8f3b8
--- /dev/null
+++ b/core/org.eclipse.cdt.core.linux/library/spawner.c
@@ -0,0 +1,219 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <string.h>
+#include <jni.h>
+
+#include "exec0.h"
+#include <Spawner.h>
+
+
+#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);
+ }
+}
+
+
+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;
+ char **envp;
+ int fd[3];
+ 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;
+ char **envp;
+ 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 = kill(pid, 0);
+ break;
+
+ case 2: /* INTERRUPT */
+ status = kill(pid, SIGINT);
+ break;
+
+ case 9: /* KILL */
+ status = kill(pid, SIGKILL);
+ break;
+
+ case 15: /* TERM */
+ status = kill(pid, SIGTERM);
+ break;
+
+ default:
+ 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);
+}

Back to the top