diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | include/java_lang_VMProcess.h | 2 | ||||
-rw-r--r-- | native/jni/java-lang/java_lang_VMProcess.c | 36 | ||||
-rw-r--r-- | native/jni/native-lib/cpproc.c | 17 | ||||
-rw-r--r-- | native/jni/native-lib/cpproc.h | 3 | ||||
-rw-r--r-- | vm/reference/java/lang/VMProcess.java | 17 |
6 files changed, 56 insertions, 31 deletions
@@ -1,3 +1,15 @@ +2006-09-05 Andrew John Hughes <gnu_andrew@member.fsf.org> + + * native/jni/native-lib/cpprocess.c: + (forkAndExec(char*,char*,int,int,pid_t,char*)): + Add redirection of stdout to stderr. + * native/jni/native-lib/cpprocess.h: + Added redirect argument. + * native/jni/java-lang/java_lang_VMProcess.c + (Java_java_lang_VMProcess_nativeSpawn): Readd redirect argument. + * vm/reference/java/lang/VMProcess.java: Likewise. + * include/java_lang_VMProcess.h: Regenerated. + 2006-09-05 Andreas Tobler <a.tobler@schweiz.ch> * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c: Adjust diff --git a/include/java_lang_VMProcess.h b/include/java_lang_VMProcess.h index 3029f0d9c..22617816d 100644 --- a/include/java_lang_VMProcess.h +++ b/include/java_lang_VMProcess.h @@ -10,7 +10,7 @@ extern "C" { #endif -JNIEXPORT void JNICALL Java_java_lang_VMProcess_nativeSpawn (JNIEnv *env, jobject, jobjectArray, jobjectArray, jobject); +JNIEXPORT void JNICALL Java_java_lang_VMProcess_nativeSpawn (JNIEnv *env, jobject, jobjectArray, jobjectArray, jobject, jboolean); JNIEXPORT jboolean JNICALL Java_java_lang_VMProcess_nativeReap (JNIEnv *env, jclass); JNIEXPORT void JNICALL Java_java_lang_VMProcess_nativeKill (JNIEnv *env, jclass, jlong); #undef java_lang_VMProcess_INITIAL diff --git a/native/jni/java-lang/java_lang_VMProcess.c b/native/jni/java-lang/java_lang_VMProcess.c index 915af96f1..e9d85fa65 100644 --- a/native/jni/java-lang/java_lang_VMProcess.c +++ b/native/jni/java-lang/java_lang_VMProcess.c @@ -123,7 +123,8 @@ copy_elem (JNIEnv * env, jobject stringArray, jint i) JNIEXPORT void JNICALL Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, jobjectArray cmdArray, - jobjectArray envArray, jobject dirFile) + jobjectArray envArray, jobject dirFile, + jboolean redirect) { int fds[CPIO_EXEC_NUM_PIPES]; jobject streams[CPIO_EXEC_NUM_PIPES] = { NULL, NULL, NULL }; @@ -139,6 +140,7 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, jmethodID method; jclass clazz; int i; + int pipe_count = redirect ? 2 : 3; int err; /* Check for null */ @@ -203,7 +205,8 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, goto done; } - err = cpproc_forkAndExec(strings, newEnviron, fds, &pid, dir); + /* Create inter-process pipes */ + err = cpproc_forkAndExec(strings, newEnviron, fds, pipe_count, &pid, dir); if (err != 0) { strncpy(errbuf, cpnative_getErrorString (err), sizeof(errbuf)); @@ -217,11 +220,11 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, method = (*env)->GetMethodID (env, clazz, "<init>", "(II)V"); if ((*env)->ExceptionOccurred (env)) goto done; - for (i = 0; i < CPIO_EXEC_NUM_PIPES; i++) + 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]; - const int mode = (i == CPIO_EXEC_STDIN) ? 2 : 1; + const int mode = ((i == CPIO_EXEC_STDIN) ? 2 : 1); jclass sclazz; jmethodID smethod; @@ -257,7 +260,10 @@ Java_java_lang_VMProcess_nativeSpawn (JNIEnv * env, jobject this, if ((*env)->ExceptionOccurred (env)) goto done; (*env)->CallVoidMethod (env, this, method, - streams[CPIO_EXEC_STDIN], streams[CPIO_EXEC_STDOUT], streams[CPIO_EXEC_STDERR], (jlong) pid); + streams[CPIO_EXEC_STDIN], + streams[CPIO_EXEC_STDOUT], + streams[CPIO_EXEC_STDERR], + (jlong) pid); if ((*env)->ExceptionOccurred (env)) goto done; @@ -273,7 +279,7 @@ done: * was created for a file descriptor, we don't close it because it * will get closed when the Stream object is finalized. */ - for (i = 0; i < CPIO_EXEC_NUM_PIPES; i++) + for (i = 0; i < pipe_count; i++) { const int fd = fds[i]; @@ -287,7 +293,6 @@ done: free (strings); if (dir != NULL) free(dir); - /* Done */ return; @@ -329,7 +334,7 @@ Java_java_lang_VMProcess_nativeReap (JNIEnv * env, jclass clazz) int err; /* Try to reap a child process, but don't block */ - err = cpproc_waitpid ((pid_t) -1, &status, &pid, WNOHANG); + err = cpproc_waitpid((pid_t)-1, &status, &pid, WNOHANG); if (err == 0 && pid == 0) return JNI_FALSE; @@ -338,9 +343,8 @@ Java_java_lang_VMProcess_nativeReap (JNIEnv * env, jclass clazz) { if (err == ECHILD || err == EINTR) return JNI_FALSE; - snprintf (ebuf, sizeof (ebuf), "waitpid(%ld): %s", - (long) pid, cpnative_getErrorString (err)); - + 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; @@ -383,13 +387,11 @@ Java_java_lang_VMProcess_nativeKill (JNIEnv * env, jclass clazz, jlong pid) { char ebuf[64]; int err; - - err = cpproc_kill ((pid_t) pid, SIGKILL); - + + err = cpproc_kill((pid_t) pid, SIGKILL); if (err != 0) - { - snprintf (ebuf, - sizeof (ebuf), "kill(%ld): %s", + { + snprintf (ebuf, sizeof (ebuf), "kill(%ld): %s", (long) pid, cpnative_getErrorString (err)); clazz = (*env)->FindClass (env, "java/lang/InternalError"); if ((*env)->ExceptionOccurred (env)) diff --git a/native/jni/native-lib/cpproc.c b/native/jni/native-lib/cpproc.c index 7eac62b12..b6e9030b5 100644 --- a/native/jni/native-lib/cpproc.c +++ b/native/jni/native-lib/cpproc.c @@ -53,13 +53,14 @@ static void close_all_fds(int *fds, int numFds) close(fds[i]); } -int cpproc_forkAndExec (char * const *commandLine, char * const * newEnviron, int *fds, pid_t *out_pid, const char *wd) +int cpproc_forkAndExec (char * const *commandLine, char * const * newEnviron, + int *fds, int pipe_count, pid_t *out_pid, const char *wd) { int local_fds[6]; int i; pid_t pid; - for (i = 0; i < 6; i += 2) + for (i = 0; i < (pipe_count * 2); i += 2) { if (pipe(&local_fds[i]) < 0) { @@ -78,9 +79,12 @@ int cpproc_forkAndExec (char * const *commandLine, char * const * newEnviron, in case 0: dup2(local_fds[0], 0); dup2(local_fds[3], 1); - dup2(local_fds[5], 2); + if (pipe_count == 3) + dup2(local_fds[5], 2); + else + dup2(1, 2); - close_all_fds(local_fds, 6); + close_all_fds(local_fds, pipe_count * 2); chdir(wd); if (newEnviron == NULL) @@ -95,13 +99,14 @@ int cpproc_forkAndExec (char * const *commandLine, char * const * newEnviron, in { int err = errno; - close_all_fds(local_fds, 6); + close_all_fds(local_fds, pipe_count * 2); return err; } default: close(local_fds[0]); close(local_fds[3]); - close(local_fds[5]); + if (pipe_count == 3) + close(local_fds[5]); fds[0] = local_fds[1]; fds[1] = local_fds[2]; diff --git a/native/jni/native-lib/cpproc.h b/native/jni/native-lib/cpproc.h index 6efd10712..5e8db5800 100644 --- a/native/jni/native-lib/cpproc.h +++ b/native/jni/native-lib/cpproc.h @@ -44,7 +44,8 @@ exception statement from your version. */ #define CPIO_EXEC_STDERR 2 #define CPIO_EXEC_NUM_PIPES 3 -JNIEXPORT int cpproc_forkAndExec (char * const *commandLine, char * const * newEnviron, int *fds, pid_t *pid, const char *wd); +JNIEXPORT int cpproc_forkAndExec (char * const *commandLine, char * const * newEnviron, + int *fds, int pipe_count, pid_t *pid, const char *wd); JNIEXPORT int cpproc_waitpid (pid_t pid, int *status, pid_t *outpid, int options); JNIEXPORT int cpproc_kill (pid_t pid, int signal); diff --git a/vm/reference/java/lang/VMProcess.java b/vm/reference/java/lang/VMProcess.java index 86e4a7b9a..076e5999d 100644 --- a/vm/reference/java/lang/VMProcess.java +++ b/vm/reference/java/lang/VMProcess.java @@ -95,6 +95,7 @@ final class VMProcess extends Process InputStream stdout; // process output stream InputStream stderr; // process error stream int exitValue; // process exit value + boolean redirect; // redirect stderr -> stdout // // Dedicated thread that does all the fork()'ing and wait()'ing @@ -199,7 +200,8 @@ final class VMProcess extends Process { try { - process.nativeSpawn(process.cmd, process.env, process.dir); + process.nativeSpawn(process.cmd, process.env, process.dir, + process.redirect); process.state = RUNNING; activeMap.put(new Long(process.pid), process); } @@ -218,7 +220,7 @@ final class VMProcess extends Process } // Constructor - private VMProcess(String[] cmd, String[] env, File dir) + private VMProcess(String[] cmd, String[] env, File dir, boolean redirect) throws IOException { @@ -227,6 +229,7 @@ final class VMProcess extends Process this.cmd = cmd; this.env = env; this.dir = dir; + this.redirect = redirect; // Add process to the new process work list and wakeup processThread synchronized (workList) @@ -301,10 +304,11 @@ final class VMProcess extends Process */ static Process exec(String[] cmd, String[] env, File dir) throws IOException { - return new VMProcess(cmd, env, dir); + return new VMProcess(cmd, env, dir, false); } - static Process exec(List cmd, Map env, File dir) throws IOException + static Process exec(List cmd, Map env, + File dir, boolean redirect) throws IOException { String[] acmd = (String[]) cmd.toArray(new String[cmd.size()]); String[] aenv = new String[env.size()]; @@ -317,7 +321,7 @@ final class VMProcess extends Process aenv[i++] = entry.getKey() + "=" + entry.getValue(); } - return new VMProcess(acmd, aenv, dir); + return new VMProcess(acmd, aenv, dir, redirect); } public OutputStream getOutputStream() @@ -376,7 +380,8 @@ final class VMProcess extends Process * * @throws IOException if the O/S process could not be created. */ - native void nativeSpawn(String[] cmd, String[] env, File dir) + native void nativeSpawn(String[] cmd, String[] env, File dir, + boolean redirect) throws IOException; /** |