summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/native/jni/java-lang/java_lang_VMProcess.c
diff options
context:
space:
mode:
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.c185
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;
OpenPOWER on IntegriCloud