natRuntime.cc 7.1 KB

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