PR java/29812:
[official-gcc.git] / libjava / java / lang / natRuntime.cc
blob64c8fbb3f90945bacda1e3b6ca851dfa7718f63c
1 // natRuntime.cc - Implementation of native side of Runtime class.
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9 details. */
11 #include <config.h>
12 #include <platform.h>
14 #include <stdlib.h>
16 #include <gcj/cni.h>
17 #include <jvm.h>
18 #include <java-props.h>
19 #include <java-stack.h>
20 #include <java/lang/Long.h>
21 #include <java/lang/Runtime.h>
22 #include <java/lang/UnknownError.h>
23 #include <java/lang/UnsatisfiedLinkError.h>
24 #include <gnu/gcj/runtime/FinalizerThread.h>
25 #include <java/io/File.h>
26 #include <java/util/TimeZone.h>
27 #include <java/lang/StringBuffer.h>
28 #include <java/lang/Process.h>
29 #include <java/lang/ClassLoader.h>
31 // It is convenient and safe to simply include all of these.
32 #include <java/lang/Win32Process.h>
33 #include <java/lang/EcosProcess.h>
34 #include <java/lang/PosixProcess.h>
36 #include <jni.h>
38 #ifdef HAVE_PWD_H
39 #include <pwd.h>
40 #endif
41 #include <errno.h>
43 #ifdef HAVE_LOCALE_H
44 #include <locale.h>
45 #endif
47 #ifdef HAVE_LANGINFO_H
48 #include <langinfo.h>
49 #endif
53 #ifdef USE_LTDL
54 #include <ltdl.h>
56 /* FIXME: we don't always need this. The next libtool will let us use
57 AC_LTDL_PREOPEN to see if we do. */
58 extern const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
60 struct lookup_data
62 const char *symname;
63 void *result;
66 static int
67 find_symbol (lt_dlhandle handle, lt_ptr data)
69 lookup_data *ld = (lookup_data *) data;
70 ld->result = lt_dlsym (handle, ld->symname);
71 return ld->result != NULL;
74 void *
75 _Jv_FindSymbolInExecutable (const char *symname)
77 lookup_data data;
78 data.symname = symname;
79 data.result = NULL;
80 lt_dlforeach (find_symbol, (lt_ptr) &data);
81 return data.result;
84 #else
86 void *
87 _Jv_FindSymbolInExecutable (const char *)
89 return NULL;
92 #endif /* USE_LTDL */
96 void
97 java::lang::Runtime::runFinalizationForExit ()
99 if (finalizeOnExit)
100 _Jv_RunAllFinalizers ();
103 void
104 java::lang::Runtime::exitInternal (jint status)
106 // Make status right for Unix. This is perhaps strange.
107 if (status < 0 || status > 255)
108 status = 255;
110 ::exit (status);
113 jlong
114 java::lang::Runtime::freeMemory (void)
116 return _Jv_GCFreeMemory ();
119 void
120 java::lang::Runtime::gc (void)
122 _Jv_RunGC ();
125 #ifdef USE_LTDL
126 // List of names for JNI_OnLoad.
127 static const char *onload_names[] = _Jv_platform_onload_names;
128 #endif
130 void
131 java::lang::Runtime::_load (jstring path, jboolean do_search)
133 JvSynchronize sync (this);
134 using namespace java::lang;
135 #ifdef USE_LTDL
136 jint len = _Jv_GetStringUTFLength (path);
137 char buf[len + 1 + strlen (_Jv_platform_solib_prefix)
138 + strlen (_Jv_platform_solib_suffix)];
139 int offset = 0;
140 if (do_search)
142 strcpy (buf, _Jv_platform_solib_prefix);
143 offset = strlen (_Jv_platform_solib_prefix);
145 jsize total = JvGetStringUTFRegion (path, 0, path->length(), &buf[offset]);
146 buf[offset + total] = '\0';
148 char *lib_name = buf;
150 if (do_search)
152 ClassLoader *look = _Jv_StackTrace::GetFirstNonSystemClassLoader ();
154 if (look != NULL)
156 // Don't include solib prefix in string passed to
157 // findLibrary.
158 jstring name = look->findLibrary(JvNewStringUTF(&buf[offset]));
159 if (name != NULL)
161 len = _Jv_GetStringUTFLength (name);
162 lib_name = (char *) _Jv_AllocBytes(len + 1);
163 total = JvGetStringUTFRegion (name, 0,
164 name->length(), lib_name);
165 lib_name[total] = '\0';
166 // Don't append suffixes any more; we have the full file
167 // name.
168 do_search = false;
173 lt_dlhandle h;
174 // FIXME: make sure path is absolute.
176 // Synchronize on java.lang.Class. This is to protect the class chain from
177 // concurrent modification by class registration calls which may be run
178 // during the dlopen().
179 JvSynchronize sync (&java::lang::Class::class$);
180 h = do_search ? lt_dlopenext (lib_name) : lt_dlopen (lib_name);
182 if (h == NULL)
184 const char *msg = lt_dlerror ();
185 jstring str = JvNewStringLatin1 (lib_name);
186 str = str->concat (JvNewStringLatin1 (": "));
187 str = str->concat (JvNewStringLatin1 (msg));
188 throw new UnsatisfiedLinkError (str);
191 // Search for JNI_OnLoad function.
192 void *onload = NULL;
193 const char **name = onload_names;
194 while (*name != NULL)
196 onload = lt_dlsym (h, *name);
197 if (onload != NULL)
198 break;
199 ++name;
202 if (onload != NULL)
204 JavaVM *vm = _Jv_GetJavaVM ();
205 if (vm == NULL)
207 // FIXME: what?
208 return;
211 // Push a new frame so that JNI_OnLoad will get the right class
212 // loader if it calls FindClass.
213 ::java::lang::ClassLoader *loader
214 = _Jv_StackTrace::GetFirstNonSystemClassLoader();
215 JNIEnv *env = _Jv_GetJNIEnvNewFrameWithLoader (loader);
216 jint vers = ((jint (JNICALL *) (JavaVM *, void *)) onload) (vm, NULL);
217 _Jv_JNI_PopSystemFrame (env);
218 if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2
219 && vers != JNI_VERSION_1_4)
221 // FIXME: unload the library.
222 throw new UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from JNI_OnLoad"));
225 #else
226 throw new UnknownError
227 (JvNewStringLatin1 (do_search
228 ? "Runtime.loadLibrary not implemented"
229 : "Runtime.load not implemented"));
230 #endif /* USE_LTDL */
233 jboolean
234 java::lang::Runtime::loadLibraryInternal (jstring lib)
236 JvSynchronize sync (this);
237 using namespace java::lang;
238 #ifdef USE_LTDL
239 jint len = _Jv_GetStringUTFLength (lib);
240 char buf[len + 1];
241 jsize total = JvGetStringUTFRegion (lib, 0, lib->length(), buf);
242 buf[total] = '\0';
243 // FIXME: make sure path is absolute.
244 lt_dlhandle h = lt_dlopenext (buf);
245 return h != NULL;
246 #else
247 return false;
248 #endif /* USE_LTDL */
251 void
252 java::lang::Runtime::init (void)
254 #ifdef USE_LTDL
255 lt_dlinit ();
256 // Set module load path.
257 lt_dlsetsearchpath (_Jv_Module_Load_Path);
258 // Make sure self is opened.
259 lt_dlopen (NULL);
260 #endif
263 void
264 java::lang::Runtime::runFinalization (void)
266 gnu::gcj::runtime::FinalizerThread::finalizerReady ();
269 jlong
270 java::lang::Runtime::totalMemory (void)
272 return _Jv_GCTotalMemory ();
275 jlong
276 java::lang::Runtime::maxMemory (void)
278 // We don't have a maximum. FIXME: we might if we ask the GC for
279 // one.
280 return Long::MAX_VALUE;
283 void
284 java::lang::Runtime::traceInstructions (jboolean)
286 // Do nothing.
289 void
290 java::lang::Runtime::traceMethodCalls (jboolean)
292 // Do nothing.
295 java::lang::Process *
296 java::lang::Runtime::execInternal (jstringArray cmd,
297 jstringArray env,
298 java::io::File *dir)
300 return new _Jv_platform_process (cmd, env, dir);
303 jint
304 java::lang::Runtime::availableProcessors (void)
306 // FIXME: find the real value.
307 return 1;
310 jstring
311 java::lang::Runtime::nativeGetLibname (jstring pathname, jstring libname)
313 java::lang::StringBuffer *sb = new java::lang::StringBuffer ();
314 sb->append(pathname);
315 if (pathname->length() > 0)
316 sb->append (_Jv_platform_file_separator);
318 sb->append (JvNewStringLatin1 (_Jv_platform_solib_prefix));
319 sb->append(libname);
320 sb->append (JvNewStringLatin1 (_Jv_platform_solib_suffix));
322 return sb->toString();