diff options
Diffstat (limited to 'libjava/classpath/native/jni/java-lang/java_lang_VMProcess.c')
-rw-r--r-- | libjava/classpath/native/jni/java-lang/java_lang_VMProcess.c | 185 |
1 files changed, 47 insertions, 138 deletions
diff --git a/libjava/classpath/native/jni/java-lang/java_lang_VMProcess.c b/libjava/classpath/native/jni/java-lang/java_lang_VMProcess.c index f13a94f1889..a6076f2aea9 100644 --- a/libjava/classpath/native/jni/java-lang/java_lang_VMProcess.c +++ b/libjava/classpath/native/jni/java-lang/java_lang_VMProcess.c @@ -38,7 +38,7 @@ exception statement from your version. */ #include <config.h> #include "java_lang_VMProcess.h" -#include "gnu_java_nio_channels_FileChannelImpl.h" +#include "gnu_java_nio_FileChannelImpl.h" #include <sys/types.h> #include <sys/wait.h> @@ -50,10 +50,8 @@ exception statement from your version. */ #include <fcntl.h> #include <stdio.h> -#include <jcl.h> - -#include "target_native.h" -#include "target_native_misc.h" +#include "cpnative.h" +#include "cpproc.h" /* Internal functions */ static char *copy_string (JNIEnv * env, jobject string); @@ -65,7 +63,6 @@ static char *copy_elem (JNIEnv * env, jobject stringArray, jint i); static char * copy_string (JNIEnv * env, jobject string) { - char errbuf[64]; const char *utf; jclass clazz; char *copy; @@ -89,12 +86,10 @@ copy_string (JNIEnv * env, jobject string) /* Copy it */ if ((copy = strdup (utf)) == NULL) { - TARGET_NATIVE_MISC_FORMAT_STRING1 (errbuf, sizeof (errbuf), - "strdup: %s", strerror (errno)); clazz = (*env)->FindClass (env, "java/lang/InternalError"); if ((*env)->ExceptionOccurred (env)) return NULL; - (*env)->ThrowNew (env, clazz, errbuf); + (*env)->ThrowNew (env, clazz, "strdup returned NULL"); (*env)->DeleteLocalRef (env, clazz); } @@ -131,8 +126,8 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, jobjectArray envArray, jobject dirFile, jboolean redirect) { - int fds[3][2] = { {-1, -1}, {-1, -1}, {-1, -1} }; - jobject streams[3] = { NULL, NULL, NULL }; + int fds[CPIO_EXEC_NUM_PIPES]; + jobject streams[CPIO_EXEC_NUM_PIPES] = { NULL, NULL, NULL }; jobject dirString = NULL; char **newEnviron = NULL; jsize cmdArrayLen = 0; @@ -142,10 +137,11 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, char *dir = NULL; pid_t pid = -1; char errbuf[64]; - jmethodID method; - jclass clazz; + jmethodID method, vmmethod; + jclass clazz, vmclazz; int i; int pipe_count = redirect ? 2 : 3; + int err; /* Check for null */ if (cmdArray == NULL) @@ -182,9 +178,7 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, + (dirString != NULL ? 1 : 0)) * sizeof (*strings))) == NULL) { - TARGET_NATIVE_MISC_FORMAT_STRING1 (errbuf, - sizeof (errbuf), "malloc: %s", - strerror (errno)); + strncpy (errbuf, "malloc failed", sizeof(errbuf)); goto out_of_memory; } @@ -209,125 +203,43 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, { if ((dir = copy_string (env, dirString)) == NULL) goto done; - strings[num_strings++] = dir; } /* Create inter-process pipes */ - for (i = 0; i < pipe_count; i++) - { - if (pipe (fds[i]) == -1) - { - TARGET_NATIVE_MISC_FORMAT_STRING1 (errbuf, - sizeof (errbuf), "pipe: %s", - strerror (errno)); - goto system_error; - } - } - - /* Set close-on-exec flag for parent's ends of pipes */ - (void) fcntl (fds[0][1], F_SETFD, 1); - (void) fcntl (fds[1][0], F_SETFD, 1); - if (pipe_count == 3) - (void) fcntl (fds[2][0], F_SETFD, 1); - - /* Fork into parent and child processes */ - if ((pid = fork ()) == (pid_t) - 1) + err = cpproc_forkAndExec(strings, newEnviron, fds, pipe_count, &pid, dir); + if (err != 0) { - TARGET_NATIVE_MISC_FORMAT_STRING1 (errbuf, - sizeof (errbuf), "fork: %s", - strerror (errno)); + strncpy(errbuf, cpnative_getErrorString (err), sizeof(errbuf)); goto system_error; } - /* Child becomes the new process */ - if (pid == 0) - { - char *const path = strings[0]; - - /* Move file descriptors to standard locations */ - if (fds[0][0] != 0) - { - if (dup2 (fds[0][0], 0) == -1) - { - fprintf (stderr, "dup2: %s", strerror (errno)); - exit (127); - } - close (fds[0][0]); - } - if (fds[1][1] != 1) - { - if (dup2 (fds[1][1], 1) == -1) - { - fprintf (stderr, "dup2: %s", strerror (errno)); - exit (127); - } - close (fds[1][1]); - } - if (pipe_count == 2) - { - /* Duplicate stdout to stderr. */ - if (dup2 (1, 2) == -1) - { - fprintf (stderr, "dup2: %s", strerror (errno)); - exit (127); - } - } - else if (fds[2][1] != 2) - { - if (dup2 (fds[2][1], 2) == -1) - { - fprintf (stderr, "dup2: %s", strerror (errno)); - exit (127); - } - close (fds[2][1]); - } - - /* Change into destination directory */ - if (dir != NULL && chdir (dir) == -1) - { - fprintf (stderr, "%s: %s", dir, strerror (errno)); - exit (127); - } - - /* Make argv[0] last component of executable pathname */ - /* XXX should use "file.separator" property here XXX */ - for (i = strlen (path); i > 0 && path[i - 1] != '/'; i--); - strings[0] = path + i; - - /* Set new environment */ - if (newEnviron != NULL) - environ = newEnviron; - - /* Execute new program (this will close the parent end of the pipes) */ - execvp (path, strings); - - /* Failed */ - fprintf (stderr, "%s: %s", path, strerror (errno)); - exit (127); - } - /* Create Input/OutputStream objects around parent file descriptors */ - clazz = (*env)->FindClass (env, "gnu/java/nio/channels/FileChannelImpl"); + vmclazz = (*env)->FindClass (env, "gnu/java/nio/VMChannel"); + clazz = (*env)->FindClass (env, "gnu/java/nio/FileChannelImpl"); if ((*env)->ExceptionOccurred (env)) goto done; - method = (*env)->GetMethodID (env, clazz, "<init>", "(II)V"); + vmmethod = (*env)->GetMethodID (env, vmclazz, "<init>", "(I)V"); + method = (*env)->GetMethodID (env, clazz, "<init>", "(Lgnu/java/nio/VMChannel;I)V"); if ((*env)->ExceptionOccurred (env)) goto done; for (i = 0; i < pipe_count; i++) { /* Mode is WRITE (2) for in and READ (1) for out and err. */ - const int fd = fds[i][i == 0]; - const int mode = ((i == 0) - ? gnu_java_nio_channels_FileChannelImpl_WRITE - : gnu_java_nio_channels_FileChannelImpl_READ); + const int fd = fds[i]; + const int mode = ((i == CPIO_EXEC_STDIN) ? 2 : 1); jclass sclazz; jmethodID smethod; - jobject channel = (*env)->NewObject (env, clazz, method, fd, mode); + jobject vmchannel; + jobject channel; + vmchannel = (*env)->NewObject (env, vmclazz, vmmethod, fd); + if ((*env)->ExceptionOccurred (env)) + goto done; + channel = (*env)->NewObject (env, clazz, method, vmchannel, mode); if ((*env)->ExceptionOccurred (env)) goto done; - if (mode == gnu_java_nio_channels_FileChannelImpl_WRITE) + if (mode == gnu_java_nio_FileChannelImpl_WRITE) sclazz = (*env)->FindClass (env, "java/io/FileOutputStream"); else sclazz = (*env)->FindClass (env, "java/io/FileInputStream"); @@ -335,7 +247,7 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, goto done; smethod = (*env)->GetMethodID (env, sclazz, "<init>", - "(Lgnu/java/nio/channels/FileChannelImpl;)V"); + "(Lgnu/java/nio/FileChannelImpl;)V"); if ((*env)->ExceptionOccurred (env)) goto done; @@ -355,7 +267,10 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, if ((*env)->ExceptionOccurred (env)) goto done; (*env)->CallVoidMethod (env, this, method, - streams[0], streams[1], streams[2], (jlong) pid); + streams[CPIO_EXEC_STDIN], + streams[CPIO_EXEC_STDOUT], + streams[CPIO_EXEC_STDERR], + (jlong) pid); if ((*env)->ExceptionOccurred (env)) goto done; @@ -365,15 +280,6 @@ done: * parent process. Our goal is to clean up the mess we created. */ - /* Close child's ends of pipes */ - for (i = 0; i < pipe_count; i++) - { - const int fd = fds[i][i != 0]; - - if (fd != -1) - close (fd); - } - /* * Close parent's ends of pipes if Input/OutputStreams never got created. * This can only happen in a failure case. If a Stream object @@ -382,7 +288,7 @@ done: */ for (i = 0; i < pipe_count; i++) { - const int fd = fds[i][i == 0]; + const int fd = fds[i]; if (fd != -1 && streams[i] == NULL) close (fd); @@ -392,7 +298,8 @@ done: while (num_strings > 0) free (strings[--num_strings]); free (strings); - + if (dir != NULL) + free(dir); /* Done */ return; @@ -431,19 +338,20 @@ Java_java_lang_VMProcess_nativeReap (JNIEnv * env, jclass clazz) jfieldID field; jint status; pid_t pid; + int err; /* Try to reap a child process, but don't block */ - if ((pid = waitpid ((pid_t) - 1, &status, WNOHANG)) == 0) + err = cpproc_waitpid((pid_t)-1, &status, &pid, WNOHANG); + if (err == 0 && pid == 0) return JNI_FALSE; /* Check result from waitpid() */ - if (pid == (pid_t) - 1) + if (err != 0) { - if (errno == ECHILD || errno == EINTR) + if (err == ECHILD || err == EINTR) return JNI_FALSE; - TARGET_NATIVE_MISC_FORMAT_STRING2 (ebuf, - sizeof (ebuf), "waitpid(%ld): %s", - (long) pid, strerror (errno)); + snprintf(ebuf, sizeof (ebuf), "waitpid(%ld): %s", + (long) pid, cpnative_getErrorString(errno)); clazz = (*env)->FindClass (env, "java/lang/InternalError"); if ((*env)->ExceptionOccurred (env)) return JNI_FALSE; @@ -485,12 +393,13 @@ JNIEXPORT void JNICALL Java_java_lang_VMProcess_nativeKill (JNIEnv * env, jclass clazz, jlong pid) { char ebuf[64]; - - if (kill ((pid_t) pid, SIGKILL) == -1) + int err; + + err = cpproc_kill((pid_t) pid, SIGKILL); + if (err != 0) { - TARGET_NATIVE_MISC_FORMAT_STRING2 (ebuf, - sizeof (ebuf), "kill(%ld): %s", - (long) pid, strerror (errno)); + snprintf (ebuf, sizeof (ebuf), "kill(%ld): %s", + (long) pid, cpnative_getErrorString (err)); clazz = (*env)->FindClass (env, "java/lang/InternalError"); if ((*env)->ExceptionOccurred (env)) return; |