summaryrefslogtreecommitdiff
path: root/libjava/java/lang/natRuntime.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/lang/natRuntime.cc')
-rw-r--r--libjava/java/lang/natRuntime.cc323
1 files changed, 323 insertions, 0 deletions
diff --git a/libjava/java/lang/natRuntime.cc b/libjava/java/lang/natRuntime.cc
new file mode 100644
index 000000000..02842b1df
--- /dev/null
+++ b/libjava/java/lang/natRuntime.cc
@@ -0,0 +1,323 @@
+// natRuntime.cc - Implementation of native side of Runtime class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
+
+ 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>
+#include <platform.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-props.h>
+#include <java-stack.h>
+#include <java/lang/Long.h>
+#include <java/lang/Runtime.h>
+#include <java/lang/UnknownError.h>
+#include <java/lang/UnsatisfiedLinkError.h>
+#include <gnu/gcj/runtime/FinalizerThread.h>
+#include <java/io/File.h>
+#include <java/util/TimeZone.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/Process.h>
+#include <java/lang/ClassLoader.h>
+
+// It is convenient and safe to simply include all of these.
+#include <java/lang/Win32Process.h>
+#include <java/lang/EcosProcess.h>
+#include <java/lang/PosixProcess.h>
+
+#include <jni.h>
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#include <errno.h>
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+
+
+
+#ifdef USE_LTDL
+#include <ltdl.h>
+
+/* FIXME: we don't always need this. The next libtool will let us use
+ AC_LTDL_PREOPEN to see if we do. */
+extern const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
+
+struct lookup_data
+{
+ const char *symname;
+ void *result;
+};
+
+static int
+find_symbol (lt_dlhandle handle, lt_ptr data)
+{
+ lookup_data *ld = (lookup_data *) data;
+ ld->result = lt_dlsym (handle, ld->symname);
+ return ld->result != NULL;
+}
+
+void *
+_Jv_FindSymbolInExecutable (const char *symname)
+{
+ lookup_data data;
+ data.symname = symname;
+ data.result = NULL;
+ lt_dlforeach (find_symbol, (lt_ptr) &data);
+ return data.result;
+}
+
+#else
+
+void *
+_Jv_FindSymbolInExecutable (const char *)
+{
+ return NULL;
+}
+
+#endif /* USE_LTDL */
+
+
+
+void
+java::lang::Runtime::runFinalizationForExit ()
+{
+ if (finalizeOnExit)
+ _Jv_RunAllFinalizers ();
+}
+
+void
+java::lang::Runtime::exitInternal (jint status)
+{
+ // Make status right for Unix. This is perhaps strange.
+ if (status < 0 || status > 255)
+ status = 255;
+
+ ::exit (status);
+}
+
+jlong
+java::lang::Runtime::freeMemory (void)
+{
+ return _Jv_GCFreeMemory ();
+}
+
+void
+java::lang::Runtime::gc (void)
+{
+ _Jv_RunGC ();
+}
+
+#ifdef USE_LTDL
+// List of names for JNI_OnLoad.
+static const char *onload_names[] = _Jv_platform_onload_names;
+#endif
+
+void
+java::lang::Runtime::_load (jstring path, jboolean do_search)
+{
+ JvSynchronize sync (this);
+ using namespace java::lang;
+#ifdef USE_LTDL
+ jint len = _Jv_GetStringUTFLength (path);
+ char buf[len + 1 + strlen (_Jv_platform_solib_prefix)
+ + strlen (_Jv_platform_solib_suffix)];
+ int offset = 0;
+ if (do_search)
+ {
+ strcpy (buf, _Jv_platform_solib_prefix);
+ offset = strlen (_Jv_platform_solib_prefix);
+ }
+ jsize total = JvGetStringUTFRegion (path, 0, path->length(), &buf[offset]);
+ buf[offset + total] = '\0';
+
+ char *lib_name = buf;
+
+ if (do_search)
+ {
+ ClassLoader *look = _Jv_StackTrace::GetFirstNonSystemClassLoader ();
+
+ if (look != NULL)
+ {
+ // Don't include solib prefix in string passed to
+ // findLibrary.
+ jstring name = look->findLibrary(JvNewStringUTF(&buf[offset]));
+ if (name != NULL)
+ {
+ len = _Jv_GetStringUTFLength (name);
+ lib_name = (char *) _Jv_AllocBytes(len + 1);
+ total = JvGetStringUTFRegion (name, 0,
+ name->length(), lib_name);
+ lib_name[total] = '\0';
+ // Don't append suffixes any more; we have the full file
+ // name.
+ do_search = false;
+ }
+ }
+ }
+
+ lt_dlhandle h;
+ // FIXME: make sure path is absolute.
+ {
+ // Synchronize on java.lang.Class. This is to protect the class chain from
+ // concurrent modification by class registration calls which may be run
+ // during the dlopen().
+ JvSynchronize sync (&java::lang::Class::class$);
+ h = do_search ? lt_dlopenext (lib_name) : lt_dlopen (lib_name);
+ }
+ if (h == NULL)
+ {
+ const char *msg = lt_dlerror ();
+ jstring str = JvNewStringLatin1 (lib_name);
+ str = str->concat (JvNewStringLatin1 (": "));
+ str = str->concat (JvNewStringLatin1 (msg));
+ throw new UnsatisfiedLinkError (str);
+ }
+
+ // Search for JNI_OnLoad function.
+ void *onload = NULL;
+ const char **name = onload_names;
+ while (*name != NULL)
+ {
+ onload = lt_dlsym (h, *name);
+ if (onload != NULL)
+ break;
+ ++name;
+ }
+
+ if (onload != NULL)
+ {
+ JavaVM *vm = _Jv_GetJavaVM ();
+ if (vm == NULL)
+ {
+ // FIXME: what?
+ return;
+ }
+
+ // Push a new frame so that JNI_OnLoad will get the right class
+ // loader if it calls FindClass.
+ ::java::lang::ClassLoader *loader
+ = _Jv_StackTrace::GetFirstNonSystemClassLoader();
+ JNIEnv *env = _Jv_GetJNIEnvNewFrameWithLoader (loader);
+ jint vers = ((jint (JNICALL *) (JavaVM *, void *)) onload) (vm, NULL);
+ _Jv_JNI_PopSystemFrame (env);
+ if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2
+ && vers != JNI_VERSION_1_4)
+ {
+ // FIXME: unload the library.
+ throw new UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from JNI_OnLoad"));
+ }
+ }
+#else
+ throw new UnknownError
+ (JvNewStringLatin1 (do_search
+ ? "Runtime.loadLibrary not implemented"
+ : "Runtime.load not implemented"));
+#endif /* USE_LTDL */
+}
+
+jboolean
+java::lang::Runtime::loadLibraryInternal (jstring lib)
+{
+ JvSynchronize sync (this);
+ using namespace java::lang;
+#ifdef USE_LTDL
+ jint len = _Jv_GetStringUTFLength (lib);
+ char buf[len + 1];
+ jsize total = JvGetStringUTFRegion (lib, 0, lib->length(), buf);
+ buf[total] = '\0';
+ // FIXME: make sure path is absolute.
+ lt_dlhandle h = lt_dlopenext (buf);
+ return h != NULL;
+#else
+ return false;
+#endif /* USE_LTDL */
+}
+
+void
+java::lang::Runtime::init (void)
+{
+#ifdef USE_LTDL
+ lt_dlinit ();
+ // Set module load path.
+ lt_dlsetsearchpath (_Jv_Module_Load_Path);
+ // Make sure self is opened.
+ lt_dlopen (NULL);
+#endif
+}
+
+void
+java::lang::Runtime::runFinalization (void)
+{
+ gnu::gcj::runtime::FinalizerThread::finalizerReady ();
+}
+
+jlong
+java::lang::Runtime::totalMemory (void)
+{
+ return _Jv_GCTotalMemory ();
+}
+
+jlong
+java::lang::Runtime::maxMemory (void)
+{
+ // We don't have a maximum. FIXME: we might if we ask the GC for
+ // one.
+ return Long::MAX_VALUE;
+}
+
+void
+java::lang::Runtime::traceInstructions (jboolean)
+{
+ // Do nothing.
+}
+
+void
+java::lang::Runtime::traceMethodCalls (jboolean)
+{
+ // Do nothing.
+}
+
+java::lang::Process *
+java::lang::Runtime::execInternal (jstringArray cmd,
+ jstringArray env,
+ java::io::File *dir)
+{
+ return new _Jv_platform_process (cmd, env, dir, false);
+}
+
+jint
+java::lang::Runtime::availableProcessors (void)
+{
+ // FIXME: find the real value.
+ return 1;
+}
+
+jstring
+java::lang::Runtime::nativeGetLibname (jstring pathname, jstring libname)
+{
+ java::lang::StringBuffer *sb = new java::lang::StringBuffer ();
+ sb->append(pathname);
+ if (pathname->length() > 0)
+ sb->append (_Jv_platform_file_separator);
+
+ sb->append (JvNewStringLatin1 (_Jv_platform_solib_prefix));
+ sb->append(libname);
+ sb->append (JvNewStringLatin1 (_Jv_platform_solib_suffix));
+
+ return sb->toString();
+}