Mark as release
[official-gcc.git] / libjava / java / lang / natRuntime.cc
bloba59ec4bada4c15365414e42eb83ed9e049c98063
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/ConcreteProcess.h>
30 #include <java/lang/ClassLoader.h>
32 #include <jni.h>
34 #ifdef HAVE_PWD_H
35 #include <pwd.h>
36 #endif
37 #include <errno.h>
39 #ifdef HAVE_LOCALE_H
40 #include <locale.h>
41 #endif
43 #ifdef HAVE_LANGINFO_H
44 #include <langinfo.h>
45 #endif
49 #ifdef USE_LTDL
50 #include <ltdl.h>
52 /* FIXME: we don't always need this. The next libtool will let us use
53 AC_LTDL_PREOPEN to see if we do. */
54 extern const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
56 struct lookup_data
58 const char *symname;
59 void *result;
62 static int
63 find_symbol (lt_dlhandle handle, lt_ptr data)
65 lookup_data *ld = (lookup_data *) data;
66 ld->result = lt_dlsym (handle, ld->symname);
67 return ld->result != NULL;
70 void *
71 _Jv_FindSymbolInExecutable (const char *symname)
73 lookup_data data;
74 data.symname = symname;
75 data.result = NULL;
76 lt_dlforeach (find_symbol, (lt_ptr) &data);
77 return data.result;
80 #else
82 void *
83 _Jv_FindSymbolInExecutable (const char *)
85 return NULL;
88 #endif /* USE_LTDL */
92 void
93 java::lang::Runtime::runFinalizationForExit ()
95 if (finalizeOnExit)
96 _Jv_RunAllFinalizers ();
99 void
100 java::lang::Runtime::exitInternal (jint status)
102 // Make status right for Unix. This is perhaps strange.
103 if (status < 0 || status > 255)
104 status = 255;
106 ::exit (status);
109 jlong
110 java::lang::Runtime::freeMemory (void)
112 return _Jv_GCFreeMemory ();
115 void
116 java::lang::Runtime::gc (void)
118 _Jv_RunGC ();
121 #ifdef USE_LTDL
122 // List of names for JNI_OnLoad.
123 static const char *onload_names[] = _Jv_platform_onload_names;
124 #endif
126 void
127 java::lang::Runtime::_load (jstring path, jboolean do_search)
129 JvSynchronize sync (this);
130 using namespace java::lang;
131 #ifdef USE_LTDL
132 jint len = _Jv_GetStringUTFLength (path);
133 char buf[len + 1 + strlen (_Jv_platform_solib_prefix)
134 + strlen (_Jv_platform_solib_suffix)];
135 int offset = 0;
136 if (do_search)
138 strcpy (buf, _Jv_platform_solib_prefix);
139 offset = strlen (_Jv_platform_solib_prefix);
141 jsize total = JvGetStringUTFRegion (path, 0, path->length(), &buf[offset]);
142 buf[offset + total] = '\0';
144 char *lib_name = buf;
146 if (do_search)
148 ClassLoader *look = _Jv_StackTrace::GetFirstNonSystemClassLoader ();
150 if (look != NULL)
152 // Don't include solib prefix in string passed to
153 // findLibrary.
154 jstring name = look->findLibrary(JvNewStringUTF(&buf[offset]));
155 if (name != NULL)
157 len = _Jv_GetStringUTFLength (name);
158 lib_name = (char *) _Jv_AllocBytes(len + 1);
159 total = JvGetStringUTFRegion (name, 0,
160 name->length(), lib_name);
161 lib_name[total] = '\0';
162 // Don't append suffixes any more; we have the full file
163 // name.
164 do_search = false;
169 lt_dlhandle h;
170 // FIXME: make sure path is absolute.
172 // Synchronize on java.lang.Class. This is to protect the class chain from
173 // concurrent modification by class registration calls which may be run
174 // during the dlopen().
175 JvSynchronize sync (&java::lang::Class::class$);
176 h = do_search ? lt_dlopenext (lib_name) : lt_dlopen (lib_name);
178 if (h == NULL)
180 const char *msg = lt_dlerror ();
181 jstring str = JvNewStringLatin1 (lib_name);
182 str = str->concat (JvNewStringLatin1 (": "));
183 str = str->concat (JvNewStringLatin1 (msg));
184 throw new UnsatisfiedLinkError (str);
187 // Search for JNI_OnLoad function.
188 void *onload = NULL;
189 const char **name = onload_names;
190 while (*name != NULL)
192 onload = lt_dlsym (h, *name);
193 if (onload != NULL)
194 break;
195 ++name;
198 if (onload != NULL)
200 JavaVM *vm = _Jv_GetJavaVM ();
201 if (vm == NULL)
203 // FIXME: what?
204 return;
207 // Push a new frame so that JNI_OnLoad will get the right class
208 // loader if it calls FindClass.
209 ::java::lang::ClassLoader *loader
210 = _Jv_StackTrace::GetFirstNonSystemClassLoader();
211 JNIEnv *env = _Jv_GetJNIEnvNewFrameWithLoader (loader);
212 jint vers = ((jint (JNICALL *) (JavaVM *, void *)) onload) (vm, NULL);
213 _Jv_JNI_PopSystemFrame (env);
214 if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2
215 && vers != JNI_VERSION_1_4)
217 // FIXME: unload the library.
218 throw new UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from JNI_OnLoad"));
221 #else
222 throw new UnknownError
223 (JvNewStringLatin1 (do_search
224 ? "Runtime.loadLibrary not implemented"
225 : "Runtime.load not implemented"));
226 #endif /* USE_LTDL */
229 jboolean
230 java::lang::Runtime::loadLibraryInternal (jstring lib)
232 JvSynchronize sync (this);
233 using namespace java::lang;
234 #ifdef USE_LTDL
235 jint len = _Jv_GetStringUTFLength (lib);
236 char buf[len + 1];
237 jsize total = JvGetStringUTFRegion (lib, 0, lib->length(), buf);
238 buf[total] = '\0';
239 // FIXME: make sure path is absolute.
240 lt_dlhandle h = lt_dlopenext (buf);
241 return h != NULL;
242 #else
243 return false;
244 #endif /* USE_LTDL */
247 void
248 java::lang::Runtime::init (void)
250 #ifdef USE_LTDL
251 lt_dlinit ();
252 // Set module load path.
253 lt_dlsetsearchpath (_Jv_Module_Load_Path);
254 // Make sure self is opened.
255 lt_dlopen (NULL);
256 #endif
259 void
260 java::lang::Runtime::runFinalization (void)
262 gnu::gcj::runtime::FinalizerThread::finalizerReady ();
265 jlong
266 java::lang::Runtime::totalMemory (void)
268 return _Jv_GCTotalMemory ();
271 jlong
272 java::lang::Runtime::maxMemory (void)
274 // We don't have a maximum. FIXME: we might if we ask the GC for
275 // one.
276 return Long::MAX_VALUE;
279 void
280 java::lang::Runtime::traceInstructions (jboolean)
282 // Do nothing.
285 void
286 java::lang::Runtime::traceMethodCalls (jboolean)
288 // Do nothing.
291 java::lang::Process *
292 java::lang::Runtime::execInternal (jstringArray cmd,
293 jstringArray env,
294 java::io::File *dir)
296 return new java::lang::ConcreteProcess (cmd, env, dir);
299 jint
300 java::lang::Runtime::availableProcessors (void)
302 // FIXME: find the real value.
303 return 1;
306 jstring
307 java::lang::Runtime::nativeGetLibname (jstring pathname, jstring libname)
309 java::lang::StringBuffer *sb = new java::lang::StringBuffer ();
310 sb->append(pathname);
311 if (pathname->length() > 0)
312 sb->append (_Jv_platform_file_separator);
314 sb->append (JvNewStringLatin1 (_Jv_platform_solib_prefix));
315 sb->append(libname);
316 sb->append (JvNewStringLatin1 (_Jv_platform_solib_suffix));
318 return sb->toString();