OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / native / jni / java-lang / java_lang_VMProcess.c
index f13a94f..a6076f2 100644 (file)
@@ -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;