1 // natRuntime.cc - Implementation of native side of Runtime class.
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 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
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>
47 #ifdef HAVE_LANGINFO_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 } };
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
;
75 _Jv_FindSymbolInExecutable (const char *symname
)
78 data
.symname
= symname
;
80 lt_dlforeach (find_symbol
, (lt_ptr
) &data
);
87 _Jv_FindSymbolInExecutable (const char *)
97 java::lang::Runtime::runFinalizationForExit ()
100 _Jv_RunAllFinalizers ();
104 java::lang::Runtime::exitInternal (jint status
)
106 // Make status right for Unix. This is perhaps strange.
107 if (status
< 0 || status
> 255)
114 java::lang::Runtime::freeMemory (void)
116 return _Jv_GCFreeMemory ();
120 java::lang::Runtime::gc (void)
126 // List of names for JNI_OnLoad.
127 static const char *onload_names
[] = _Jv_platform_onload_names
;
131 java::lang::Runtime::_load (jstring path
, jboolean do_search
)
133 JvSynchronize
sync (this);
134 using namespace java::lang
;
136 jint len
= _Jv_GetStringUTFLength (path
);
137 char buf
[len
+ 1 + strlen (_Jv_platform_solib_prefix
)
138 + strlen (_Jv_platform_solib_suffix
)];
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
;
152 ClassLoader
*look
= _Jv_StackTrace::GetFirstNonSystemClassLoader ();
156 // Don't include solib prefix in string passed to
158 jstring name
= look
->findLibrary(JvNewStringUTF(&buf
[offset
]));
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
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
);
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.
193 const char **name
= onload_names
;
194 while (*name
!= NULL
)
196 onload
= lt_dlsym (h
, *name
);
204 JavaVM
*vm
= _Jv_GetJavaVM ();
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"));
226 throw new UnknownError
227 (JvNewStringLatin1 (do_search
228 ? "Runtime.loadLibrary not implemented"
229 : "Runtime.load not implemented"));
230 #endif /* USE_LTDL */
234 java::lang::Runtime::loadLibraryInternal (jstring lib
)
236 JvSynchronize
sync (this);
237 using namespace java::lang
;
239 jint len
= _Jv_GetStringUTFLength (lib
);
241 jsize total
= JvGetStringUTFRegion (lib
, 0, lib
->length(), buf
);
243 // FIXME: make sure path is absolute.
244 lt_dlhandle h
= lt_dlopenext (buf
);
248 #endif /* USE_LTDL */
252 java::lang::Runtime::init (void)
256 // Set module load path.
257 lt_dlsetsearchpath (_Jv_Module_Load_Path
);
258 // Make sure self is opened.
264 java::lang::Runtime::runFinalization (void)
266 gnu::gcj::runtime::FinalizerThread::finalizerReady ();
270 java::lang::Runtime::totalMemory (void)
272 return _Jv_GCTotalMemory ();
276 java::lang::Runtime::maxMemory (void)
278 // We don't have a maximum. FIXME: we might if we ask the GC for
280 return Long::MAX_VALUE
;
284 java::lang::Runtime::traceInstructions (jboolean
)
290 java::lang::Runtime::traceMethodCalls (jboolean
)
295 java::lang::Process
*
296 java::lang::Runtime::execInternal (jstringArray cmd
,
300 return new _Jv_platform_process (cmd
, env
, dir
, false);
304 java::lang::Runtime::availableProcessors (void)
306 // FIXME: find the real value.
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
));
320 sb
->append (JvNewStringLatin1 (_Jv_platform_solib_suffix
));
322 return sb
->toString();