diff options
author | Tom Tromey <tromey@cygnus.com> | 1999-05-12 11:23:44 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 1999-05-12 11:23:44 +0000 |
commit | 42962a480a755c0f72ff8de60a6de1fbfc85affd (patch) | |
tree | abd228e8accc8f1b67bdf10c59963d3a1cc6047f /libjava/java | |
parent | 3b551e09f129c36d08e8c9635e1dab299e022fa3 (diff) | |
download | gcc-42962a480a755c0f72ff8de60a6de1fbfc85affd.zip gcc-42962a480a755c0f72ff8de60a6de1fbfc85affd.tar.gz gcc-42962a480a755c0f72ff8de60a6de1fbfc85affd.tar.bz2 |
javaprims.h: Updated namespace declarations.
* include/javaprims.h: Updated namespace declarations.
* classes.pl (scan): Uniquify class list.
* Makefile.in, configure: Rebuilt.
* Makefile.am (nat_source_files): Added natConcreteProcess.cc.
(built_java_source_files): New macro.
(nat_headers): Added built_java_source_files.
(javao_files): Likewise.
(EXTRA_libgcj_la_SOURCES): Likewise.
(libgcj.zip): Create built class files.
($(built_java_source_files:.java=.class)): New target.
(jv_convert_LDADD): Added -L$(here)/.libs.
* configure.in: Create links for ConcreteProcess.java and
natConcreteProcess.cc.
* java/lang/Runtime.java (exec): Create a ConcreteProcess.
* java/lang/natEcosProcess.cc: New file.
* java/lang/EcosProcess.java: New file.
* java/lang/PosixProcess.java: New file.
* java/lang/natPosixProcess.cc: New file.
From-SVN: r26901
Diffstat (limited to 'libjava/java')
-rw-r--r-- | libjava/java/lang/EcosProcess.java | 59 | ||||
-rw-r--r-- | libjava/java/lang/PosixProcess.java | 74 | ||||
-rw-r--r-- | libjava/java/lang/Runtime.java | 3 | ||||
-rw-r--r-- | libjava/java/lang/natEcosProcess.cc | 25 | ||||
-rw-r--r-- | libjava/java/lang/natPosixProcess.cc | 203 |
5 files changed, 362 insertions, 2 deletions
diff --git a/libjava/java/lang/EcosProcess.java b/libjava/java/lang/EcosProcess.java new file mode 100644 index 0000000..8344916 --- /dev/null +++ b/libjava/java/lang/EcosProcess.java @@ -0,0 +1,59 @@ +// EcosProcess.java - Subclass of Process for eCos systems. + +/* Copyright (C) 1998, 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +package java.lang; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; + +/** + * @author Tom Tromey <tromey@cygnus.com> + * @date May 11, 1999 + */ + +// This is entirely internal to our implementation. + +// This file is copied to `ConcreteProcess.java' before compilation. +// Hence the class name apparently does not match the file name. +final class ConcreteProcess extends Process +{ + // See natEcosProcess.cc to understand why this is native. + public native void destroy (); + + public int exitValue () + { + return 0; + } + public InputStream getErrorStream () + { + return null; + } + + public InputStream getInputStream () + { + return null; + } + + public OutputStream getOutputStream () + { + return null; + } + + public int waitFor () throws InterruptedException + { + return 0; + } + + public ConcreteProcess (String[] progarray, String[] envp) throws IOException + { + throw new IOException ("eCos processes unimplemented"); + } +} diff --git a/libjava/java/lang/PosixProcess.java b/libjava/java/lang/PosixProcess.java new file mode 100644 index 0000000..396287a --- /dev/null +++ b/libjava/java/lang/PosixProcess.java @@ -0,0 +1,74 @@ +// PosixProcess.java - Subclass of Process for POSIX systems. + +/* Copyright (C) 1998, 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +package java.lang; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; + +/** + * @author Tom Tromey <tromey@cygnus.com> + * @date May 3, 1999 + */ + +// This is entirely internal to our implementation. + +// This file is copied to `ConcreteProcess.java' before compilation. +// Hence the class name apparently does not match the file name. +final class ConcreteProcess extends Process +{ + public native void destroy (); + public native int exitValue (); + + public InputStream getErrorStream () + { + return errorStream; + } + + public InputStream getInputStream () + { + return inputStream; + } + + public OutputStream getOutputStream () + { + return outputStream; + } + + public native int waitFor () throws InterruptedException; + + // This is used for actual initialization, as we can't write a + // native constructor. + public native void startProcess (String[] progarray, String[] envp) + throws IOException; + + // This file is copied to `ConcreteProcess.java' before + // compilation. Hence the constructor name apparently does not + // match the file name. + public ConcreteProcess (String[] progarray, String[] envp) throws IOException + { + startProcess (progarray, envp); + } + + // The process id. This is cast to a pid_t on the native side. + private long pid; + + // True when child has exited. + private boolean hasExited; + + // The exit status, if the child has exited. + private int status; + + // The streams. + private InputStream errorStream; + private InputStream inputStream; + private OutputStream outputStream; +} diff --git a/libjava/java/lang/Runtime.java b/libjava/java/lang/Runtime.java index 94e7770..62a7c18 100644 --- a/libjava/java/lang/Runtime.java +++ b/libjava/java/lang/Runtime.java @@ -52,8 +52,7 @@ public class Runtime SecurityManager s = System.getSecurityManager(); if (s != null) s.checkExec(progarray[0]); - // FIXME. - return null; + return new ConcreteProcess (progarray, envp); } private final static void checkExit (int status) diff --git a/libjava/java/lang/natEcosProcess.cc b/libjava/java/lang/natEcosProcess.cc new file mode 100644 index 0000000..774a697 --- /dev/null +++ b/libjava/java/lang/natEcosProcess.cc @@ -0,0 +1,25 @@ +// natEcosProcess.cc - Native side of eCos processes. + +/* Copyright (C) 1998, 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +// The configury system needs this file to exist, since we can't +// really conditionally link files (an autoconf bug). To avoid having +// an empty translation unit, we make a single method native. FIXME. + +#include <config.h> + +#include <cni.h> +#include <jvm.h> + +#include <java/lang/ConcreteProcess.h> + +void +java::lang::ConcreteProcess::destroy (void) +{ +} diff --git a/libjava/java/lang/natPosixProcess.cc b/libjava/java/lang/natPosixProcess.cc new file mode 100644 index 0000000..30fa9d5 --- /dev/null +++ b/libjava/java/lang/natPosixProcess.cc @@ -0,0 +1,203 @@ +// natPosixProcess.cc - Native side of POSIX process code. + +/* Copyright (C) 1998, 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +#include <config.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <errno.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <signal.h> +#include <string.h> +#include <stdlib.h> + +#include <cni.h> +#include <jvm.h> + +#include <java/lang/ConcreteProcess.h> +#include <java/lang/IllegalThreadStateException.h> +#include <java/lang/InterruptedException.h> +#include <java/lang/NullPointerException.h> +#include <java/lang/Thread.h> +#include <java/io/FileDescriptor.h> +#include <java/io/FileInputStream.h> +#include <java/io/FileOutputStream.h> +#include <java/io/IOException.h> + +extern char **environ; + +void +java::lang::ConcreteProcess::destroy (void) +{ + if (! hasExited) + { + // Really kill it. + kill ((pid_t) pid, SIGKILL); + } +} + +jint +java::lang::ConcreteProcess::exitValue (void) +{ + if (! hasExited) + { + int wstat; + pid_t r = waitpid ((pid_t) pid, &wstat, WNOHANG); + if (r == -1) + { + jstring x = JvNewStringLatin1 (strerror (errno)); + _Jv_Throw (new IllegalThreadStateException (x)); + } + + hasExited = true; + // Just use the raw status. FIXME: what is right? + status = wstat; + } + + return status; +} + +jint +java::lang::ConcreteProcess::waitFor (void) +{ + if (! hasExited) + { + int wstat; + int r = waitpid ((pid_t) pid, &wstat, 0); + + if (r != -1) + { + hasExited = true; + // Just use the raw status. FIXME: what is right? + status = wstat; + } + + if (java::lang::Thread::interrupted()) + _Jv_Throw (new InterruptedException (JvNewStringLatin1 ("wait interrupted"))); + } + + return status; +} + +static char * +new_string (jstring string) +{ + jsize s = _Jv_GetStringUTFLength (string); + char *buf = (char *) _Jv_Malloc (s + 1); + _Jv_GetStringUTFRegion (string, 0, s, buf); + buf[s] = '\0'; + return buf; +} + +void +java::lang::ConcreteProcess::startProcess (jstringArray progarray, + jstringArray envp) +{ + using namespace java::io; + + hasExited = false; + + if (! progarray) + _Jv_Throw (new NullPointerException); + + // Transform arrays to native form. + // FIXME: we use malloc here. We shouldn't. If an exception is + // thrown we will leak memory. + char **args = (char **) _Jv_Malloc ((progarray->length + 1) + * sizeof (char *)); + + char **env = NULL; + if (envp) + env = (char **) _Jv_Malloc ((envp->length + 1) * sizeof (char *)); + +// for (int i = 0; i < progarray->length; ++i) +// args[i] = NULL; +// for (int i = 0; i < envp->length; ++i) +// env[i] = NULL; + + // FIXME: GC will fail here if _Jv_Malloc throws an exception. + // That's because we have to manually free the contents, but we + jstring *elts = elements (progarray); + for (int i = 0; i < progarray->length; ++i) + args[i] = new_string (elts[i]); + args[progarray->length] = NULL; + + if (envp) + { + elts = elements (envp); + for (int i = 0; i < envp->length; ++i) + args[i] = new_string (elts[i]); + args[envp->length] = NULL; + } + + // Create pipes for I/O. + int inp[2], outp[2], errp[2]; + + if (pipe (inp) + || pipe (outp) + || pipe (errp)) + { + ioerror: + // FIXME. + _Jv_Free (args); + if (env) + _Jv_Free (env); + _Jv_Throw (new IOException (JvNewStringLatin1 (strerror (errno)))); + } + + // We create the streams before forking. Otherwise if we had an + // error while creating the streams we would have run the child with + // no way to communicate with it. + errorStream = new FileInputStream (new FileDescriptor (errp[0])); + inputStream = new FileInputStream (new FileDescriptor (inp[0])); + outputStream = new FileOutputStream (new FileDescriptor (outp[1])); + + // We don't use vfork() because that would cause the local + // environment to be set by the child. + if ((pid = (jlong) fork ()) == -1) + goto ioerror; + + if (pid == 0) + { + // Child process, so remap descriptors and exec. + + if (envp) + environ = env; + + // We ignore errors from dup2 because they should never occur. + dup2 (outp[0], 0); + dup2 (inp[1], 1); + dup2 (errp[1], 2); + + close (inp[0]); + close (inp[1]); + close (errp[0]); + close (errp[1]); + close (outp[0]); + close (outp[1]); + + environ = env; + execvp (args[0], args); + _exit (127); + } + + // Parent. Close extra file descriptors and mark ours as + // close-on-exec. + close (outp[0]); + close (inp[1]); + close (errp[1]); + + fcntl (outp[1], F_SETFD, 1); + fcntl (inp[0], F_SETFD, 1); + fcntl (errp[0], F_SETFD, 1); +} |