Fix for --disable-dynamicclasspath with empty LD_LIBRARY_PATH
[cacao.git] / src / native / vm / VMRuntime.c
1 /* nat/Runtime.c - java/lang/Runtime
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Roman Obermaiser
28
29    Changes: Joseph Wenninger
30             Christian Thalinger
31
32    $Id: VMRuntime.c 1431 2004-11-02 15:22:57Z twisti $
33
34 */
35
36
37 #include <string.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <sys/utsname.h>
41 #include "main.h"
42 #include "jni.h"
43 #include "builtin.h"
44 #include "exceptions.h"
45 #include "loader.h"
46 #include "native.h"
47 #include "tables.h"
48 #include "asmpart.h"
49 #include "mm/boehm.h"
50 #include "toolbox/logging.h"
51 #include "toolbox/memory.h"
52 #include "java_io_File.h"
53 #include "java_lang_String.h"
54 #include "java_lang_Process.h"
55 #include "java_util_Properties.h"    /* needed for java_lang_Runtime.h */
56 #include "java_lang_VMRuntime.h"
57
58 #include "config.h"
59 #ifndef STATIC_CLASSPATH
60 #include <dlfcn.h>
61 #endif
62
63 #define JOWENN_DEBUG
64
65 /* should we run all finalizers on exit? */
66 static s4 finalizeOnExit = false;
67
68 #define MAXPROPS 100
69 static bool shouldFinalizersBeRunOnExit=false;
70 static int activeprops = 20;  
71    
72 static char *proplist[MAXPROPS][2] = {
73         { "java.class.path", NULL },
74         { "java.home", NULL },
75         { "user.home", NULL },  
76         { "user.name", NULL },
77         { "user.dir",  NULL },
78                                 
79         { "os.arch", NULL },
80         { "os.name", NULL },
81         { "os.version", NULL },
82         { "java.library.path",NULL},
83                                          
84         { "java.class.version", "45.3" },
85         { "java.version", PACKAGE":"VERSION },
86         { "java.vendor", "CACAO Team" },
87         { "java.vendor.url", "http://www.complang.tuwien.ac.at/java/cacao/" },
88         { "java.vm.name", "CACAO"}, 
89         { "java.tmpdir", "/tmp/"},
90         { "java.io.tmpdir", "/tmp/"},
91
92         { "path.separator", ":" },
93         { "file.separator", "/" },
94         { "line.separator", "\n" },
95         { "java.protocol.handler.pkgs", "gnu.java.net.protocol"}
96 };
97
98 void attach_property(char *name, char *value)
99 {
100         if (activeprops >= MAXPROPS) panic("Too many properties defined");
101         proplist[activeprops][0] = name;
102         proplist[activeprops][1] = value;
103         activeprops++;
104 }
105 /*
106  * Class:     java_lang_VMRuntime
107  * Method:    execInternal
108  * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/io/File;)Ljava/lang/Process;
109  */
110 JNIEXPORT java_lang_Process* JNICALL Java_java_lang_VMRuntime_execInternal(JNIEnv *env, jclass clazz, java_objectarray *cmd, java_objectarray *shellenv, java_io_File *workingdir)
111 {
112         log_text("Java_java_lang_Runtime_execInternal called");
113
114         return NULL;
115 }
116
117
118 /*
119  * Class:     java/lang/VMRuntime
120  * Method:    exitInternal
121  * Signature: (I)V
122  */
123 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_exit(JNIEnv *env, jclass clazz, s4 par1)
124 {
125         if (finalizeOnExit)
126                 gc_finalize_all();
127
128         cacao_shutdown(par1);
129 }
130
131
132 /*
133  * Class:     java/lang/Runtime
134  * Method:    freeMemory
135  * Signature: ()J
136  */
137 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_freeMemory(JNIEnv *env, jclass clazz)
138 {
139         return gc_get_free_bytes();
140 }
141
142
143 /*
144  * Class:     java/lang/Runtime
145  * Method:    gc
146  * Signature: ()V
147  */
148 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_gc(JNIEnv *env, jclass clazz)
149 {
150         gc_call();
151 }
152
153
154 /*
155  * Class:     java/lang/Runtime
156  * Method:    runFinalization
157  * Signature: ()V
158  */
159 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalization(JNIEnv *env, jclass clazz)
160 {
161         gc_invoke_finalizers();
162 }
163
164
165 /*
166  * Class:     java/lang/Runtime
167  * Method:    runFinalizersOnExit
168  * Signature: (Z)V
169  */
170 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizersOnExit(JNIEnv *env, jclass clazz, s4 par1)
171 {
172 #ifdef __GNUC__
173 #warning threading
174 #endif
175         shouldFinalizersBeRunOnExit=par1;
176 }
177
178 /*
179  * Class:     java/lang/Runtime
180  * Method:    runFinalizationsForExit
181  * Signature: ()V
182  */
183 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizationForExit(JNIEnv *env, jclass clazz)
184 {
185         if (shouldFinalizersBeRunOnExit) {
186                 gc_call();
187         //      gc_finalize_all();
188         }
189         log_text("Java_java_lang_VMRuntime_runFinalizationForExit called");
190
191 }
192
193
194 /*
195  * Class:     java/lang/Runtime
196  * Method:    totalMemory
197  * Signature: ()J
198  */
199 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_totalMemory(JNIEnv *env, jclass clazz)
200 {
201         return gc_get_heap_size();
202 }
203
204
205 /*
206  * Class:     java/lang/Runtime
207  * Method:    traceInstructions
208  * Signature: (Z)V
209  */
210 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceInstructions(JNIEnv *env, jclass clazz, s4 par1)
211 {
212         /* not supported */
213 }
214
215
216 /*
217  * Class:     java/lang/Runtime
218  * Method:    traceMethodCalls
219  * Signature: (Z)V
220  */
221 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceMethodCalls(JNIEnv *env, jclass clazz, s4 par1)
222 {
223         /* not supported */
224 }
225
226
227 /*
228  * Class:     java_lang_Runtime
229  * Method:    availableProcessors
230  * Signature: ()I
231  */
232 JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_availableProcessors(JNIEnv *env, jclass clazz)
233 {
234 #if defined(_SC_NPROC_ONLN)
235         return (s4) sysconf(_SC_NPROC_ONLN);
236
237 #elif defined(_SC_NPROCESSORS_ONLN)
238         return (s4) sysconf(_SC_NPROCESSORS_ONLN);
239
240 #else
241         return 1;
242 #endif
243 }
244
245
246 /*
247  * Class:     java_lang_Runtime
248  * Method:    nativeLoad
249  * Signature: (Ljava/lang/String;)I
250  */
251 JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass clazz, java_lang_String *par1)
252 {
253 #ifdef JOWENN_DEBUG     
254         char *buffer;
255         int buffer_len;
256         utf *data;
257         int retVal=0;
258
259         data = javastring_toutf(par1, 0);
260         
261         if (!data) {
262                 log_text("nativeLoad: Error: empty string");
263                 return 1;
264         }
265         
266         buffer_len = utf_strlen(data) + 40;
267
268                 
269         buffer = MNEW(char, buffer_len);
270 #ifndef STATIC_CLASSPATH
271         /*here it could be interesting to store the references in a list eg for nicely cleaning up or for certain platforms*/
272         if (dlopen(data->text,RTLD_NOW | RTLD_GLOBAL)) {
273                 log_text("LIBLOADED");
274                 retVal=1;
275         }
276 #else
277         retVal=1;
278 #endif
279         strcpy(buffer, "Java_java_lang_VMRuntime_nativeLoad:");
280         utf_sprint(buffer + strlen((char *) data), data);
281         log_text(buffer);       
282         
283   
284         MFREE(buffer, char, buffer_len);
285 #endif
286         log_text("Java_java_lang_VMRuntime_nativeLoad");
287
288         return retVal;
289 }
290
291
292 /*
293  * Class:     java_lang_VMRuntime
294  * Method:    nativeGetLibname
295  * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
296  */
297 JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMRuntime_nativeGetLibname(JNIEnv *env, jclass clazz, java_lang_String *par1, java_lang_String *par2)
298 {
299         char *buffer;
300         int buffer_len;
301         utf *data;
302         java_lang_String *resultString; 
303         data = javastring_toutf(par2, 0);
304         
305         if (!data) {
306                 log_text("nativeGetLibName: Error: empty string");
307                 return 0;;
308         }
309         
310         buffer_len = utf_strlen(data) + 3 /*lib*/ /*6 lib .so */ +1 /*0*/;
311         buffer = MNEW(char, buffer_len);
312         sprintf(buffer,"lib");
313         utf_sprint(buffer+3,data);
314         /*strcat(buffer,".so");*/
315         log_text("nativeGetLibName:");
316         log_text(buffer);
317         
318         resultString=javastring_new_char(buffer);       
319
320         MFREE(buffer, char, buffer_len);
321
322         return resultString;
323 }
324
325
326 /*
327  * Class:     java_lang_VMRuntime
328  * Method:    insertSystemProperties
329  * Signature: (Ljava/util/Properties;)V
330  */
331 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_insertSystemProperties(JNIEnv *env, jclass clazz, java_util_Properties *p)
332 {
333
334 #define BUFFERSIZE 200
335         u4 i;
336         methodinfo *m;
337         char buffer[BUFFERSIZE];
338         struct utsname utsnamebuf;
339
340         proplist[0][1] = classpath;
341         proplist[1][1] = getenv("JAVA_HOME");
342         proplist[2][1] = getenv("HOME");
343         proplist[3][1] = getenv("USER");
344         proplist[4][1] = getcwd(buffer, BUFFERSIZE);
345
346         /* get properties from system */
347         uname(&utsnamebuf);
348         proplist[5][1] = utsnamebuf.machine;
349         proplist[6][1] = utsnamebuf.sysname;
350         proplist[7][1] = utsnamebuf.release;
351
352 #if defined(STATIC_CLASSPATH)
353         proplist[8][1] = ".";
354 #else
355         proplist[8][1] = getenv("LD_LIBRARY_PATH");
356 #endif
357
358         if (!p) {
359                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
360                 return;
361         }
362
363         /* search for method to add properties */
364         m = class_resolvemethod(p->header.vftbl->class,
365                                                         utf_new_char("put"),
366                                                         utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;")
367                                                         );
368
369         if (!m) {
370                 *exceptionptr = new_exception_message(string_java_lang_NoSuchMethodError,
371                                                                                           "java.lang.Properties.put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;)");
372                 return;
373         }
374
375         /* add the properties */
376         for (i = 0; i < activeprops; i++) {
377
378                 if (proplist[i][1] == NULL) proplist[i][1] = "";
379
380                 asm_calljavafunction(m,
381                                                          p,
382                                                          javastring_new_char(proplist[i][0]),
383                                                          javastring_new_char(proplist[i][1]),
384                                                          NULL
385                                                          );
386         }
387
388         return;
389 }
390
391
392 /*
393  * Class:     java_lang_VMRuntime
394  * Method:    maxMemory
395  * Signature: ()J
396  */
397 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_maxMemory(JNIEnv *env, jclass clazz)
398 {
399         return gc_get_max_heap_size();
400 }
401
402
403 /*
404  * These are local overrides for various environment variables in Emacs.
405  * Please do not remove this and leave it at the end of the file, where
406  * Emacs will automagically detect them.
407  * ---------------------------------------------------------------------
408  * Local variables:
409  * mode: c
410  * indent-tabs-mode: t
411  * c-basic-offset: 4
412  * tab-width: 4
413  * End:
414  */