-ansi -pedantic fixes.
[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 1494 2004-11-12 13:34:26Z twisti $
33
34 */
35
36
37 #include <string.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <sys/utsname.h>
41 #include "exceptions.h"
42 #include "main.h"
43 #include "jni.h"
44 #include "builtin.h"
45 #include "exceptions.h"
46 #include "loader.h"
47 #include "native.h"
48 #include "tables.h"
49 #include "asmpart.h"
50 #include "mm/boehm.h"
51 #include "toolbox/logging.h"
52 #include "toolbox/memory.h"
53 #include "nat/java_io_File.h"
54 #include "nat/java_lang_String.h"
55 #include "nat/java_lang_Process.h"
56 #include "nat/java_util_Properties.h"    /* needed for java_lang_VMRuntime.h */
57 #include "nat/java_lang_VMRuntime.h"
58
59 #include "config.h"
60 #ifndef STATIC_CLASSPATH
61 #include <dlfcn.h>
62 #endif
63
64 /* this should work on BSD */
65 /*
66 #if defined(__DARWIN__)
67 #include <sys/sysctl.h>
68 #endif
69 */
70
71 #undef JOWENN_DEBUG
72
73 /* should we run all finalizers on exit? */
74 static bool finalizeOnExit = false;
75
76 /* temporary property structure */
77
78 typedef struct property property;
79
80 struct property {
81         char *key;
82         char *value;
83         property *next;
84 };
85
86 static property *properties = NULL;
87
88
89 /* create_property *************************************************************
90
91    Create a property entry for a command line property definition.
92
93 *******************************************************************************/
94
95 void create_property(char *key, char *value)
96 {
97         property *p;
98
99         p = NEW(property);
100         p->key = key;
101         p->value = value;
102         p->next = properties;
103         properties = p;
104 }
105
106
107 /* insert_property *************************************************************
108
109    Used for inserting a property into the system's properties table. Method m
110    (usually put) and the properties table must be given.
111
112 *******************************************************************************/
113
114 static void insert_property(methodinfo *m, java_util_Properties *p, char *key,
115                                                         char *value)
116 {
117         asm_calljavafunction(m,
118                                                  p,
119                                                  javastring_new_char(key),
120                                                  javastring_new_char(value),
121                                                  NULL);
122 }
123
124
125 /*
126  * Class:     java_lang_VMRuntime
127  * Method:    execInternal
128  * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/io/File;)Ljava/lang/Process;
129  */
130 JNIEXPORT java_lang_Process* JNICALL Java_java_lang_VMRuntime_execInternal(JNIEnv *env, jclass clazz, java_objectarray *cmd, java_objectarray *shellenv, java_io_File *workingdir)
131 {
132         log_text("Java_java_lang_Runtime_execInternal called");
133
134         return NULL;
135 }
136
137
138 /*
139  * Class:     java/lang/VMRuntime
140  * Method:    exitInternal
141  * Signature: (I)V
142  */
143 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_exit(JNIEnv *env, jclass clazz, s4 par1)
144 {
145         if (finalizeOnExit)
146                 gc_finalize_all();
147
148         cacao_shutdown(par1);
149 }
150
151
152 /*
153  * Class:     java/lang/Runtime
154  * Method:    freeMemory
155  * Signature: ()J
156  */
157 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_freeMemory(JNIEnv *env, jclass clazz)
158 {
159         return gc_get_free_bytes();
160 }
161
162
163 /*
164  * Class:     java/lang/Runtime
165  * Method:    gc
166  * Signature: ()V
167  */
168 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_gc(JNIEnv *env, jclass clazz)
169 {
170         gc_call();
171 }
172
173
174 /*
175  * Class:     java/lang/Runtime
176  * Method:    runFinalization
177  * Signature: ()V
178  */
179 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalization(JNIEnv *env, jclass clazz)
180 {
181         gc_invoke_finalizers();
182 }
183
184
185 /*
186  * Class:     java/lang/Runtime
187  * Method:    runFinalizersOnExit
188  * Signature: (Z)V
189  */
190 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizersOnExit(JNIEnv *env, jclass clazz, s4 value)
191 {
192 #ifdef __GNUC__
193 #warning threading
194 #endif
195         finalizeOnExit = value;
196 }
197
198
199 /*
200  * Class:     java/lang/Runtime
201  * Method:    runFinalizationsForExit
202  * Signature: ()V
203  */
204 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizationForExit(JNIEnv *env, jclass clazz)
205 {
206 /*      if (finalizeOnExit) { */
207 /*              gc_call(); */
208         /* gc_finalize_all(); */
209 /*      } */
210 /*      log_text("Java_java_lang_VMRuntime_runFinalizationForExit called"); */
211         /*gc_finalize_all();*/
212         /*gc_invoke_finalizers();*/
213         /*gc_call();*/
214 }
215
216
217 /*
218  * Class:     java/lang/Runtime
219  * Method:    totalMemory
220  * Signature: ()J
221  */
222 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_totalMemory(JNIEnv *env, jclass clazz)
223 {
224         return gc_get_heap_size();
225 }
226
227
228 /*
229  * Class:     java/lang/Runtime
230  * Method:    traceInstructions
231  * Signature: (Z)V
232  */
233 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceInstructions(JNIEnv *env, jclass clazz, s4 par1)
234 {
235         /* not supported */
236 }
237
238
239 /*
240  * Class:     java/lang/Runtime
241  * Method:    traceMethodCalls
242  * Signature: (Z)V
243  */
244 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceMethodCalls(JNIEnv *env, jclass clazz, s4 par1)
245 {
246         /* not supported */
247 }
248
249
250 /*
251  * Class:     java_lang_Runtime
252  * Method:    availableProcessors
253  * Signature: ()I
254  */
255 JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_availableProcessors(JNIEnv *env, jclass clazz)
256 {
257 #if defined(_SC_NPROC_ONLN)
258         return (s4) sysconf(_SC_NPROC_ONLN);
259
260 #elif defined(_SC_NPROCESSORS_ONLN)
261         return (s4) sysconf(_SC_NPROCESSORS_ONLN);
262
263 #elif defined(__DARWIN__)
264         /* this should work in BSD */
265         /*
266         int ncpu, mib[2], rc;
267         size_t len;
268
269         mib[0] = CTL_HW;
270         mib[1] = HW_NCPU;
271         len = sizeof(ncpu);
272         rc = sysctl(mib, 2, &ncpu, &len, NULL, 0);
273
274         return (s4) ncpu;
275         */
276
277         host_basic_info_data_t hinfo;
278         mach_msg_type_number_t hinfo_count = HOST_BASIC_INFO_COUNT;
279         kern_return_t rc;
280
281         rc = host_info(mach_host_self(), HOST_BASIC_INFO,
282                                    (host_info_t) &hinfo, &hinfo_count);
283  
284         if (rc != KERN_SUCCESS) {
285                 return -1;
286         }
287
288     return (s4) hinfo.avail_cpus;
289
290 #else
291         return 1;
292 #endif
293 }
294
295
296 /*
297  * Class:     java_lang_Runtime
298  * Method:    nativeLoad
299  * Signature: (Ljava/lang/String;)I
300  */
301 JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass clazz, java_lang_String *par1)
302 {
303         int retVal=0;
304
305         char *buffer;
306         int buffer_len;
307         utf *data;
308
309         log_text("Java_java_lang_VMRuntime_nativeLoad");
310
311         data = javastring_toutf(par1, 0);
312         
313         if (!data) {
314                 log_text("nativeLoad: Error: empty string");
315                 return 1;
316         }
317         
318         buffer_len = utf_strlen(data) + 40;
319
320                 
321         buffer = MNEW(char, buffer_len);
322         strcpy(buffer, "Java_java_lang_VMRuntime_nativeLoad:");
323         utf_sprint(buffer + strlen((char *) data), data);
324         log_text(buffer);       
325         
326   
327         MFREE(buffer, char, buffer_len);
328
329
330 #ifndef STATIC_CLASSPATH
331         /*here it could be interesting to store the references in a list eg for nicely cleaning up or for certain platforms*/
332         if (dlopen(data->text,RTLD_NOW | RTLD_GLOBAL)) {
333                 log_text("LIBLOADED");
334                 retVal=1;
335         }
336 #else
337         retVal=1;
338 #endif
339
340         return retVal;
341 }
342
343
344 /*
345  * Class:     java_lang_VMRuntime
346  * Method:    nativeGetLibname
347  * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
348  */
349 JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMRuntime_nativeGetLibname(JNIEnv *env, jclass clazz, java_lang_String *par1, java_lang_String *par2)
350 {
351         char *buffer;
352         int buffer_len;
353         utf *data;
354         java_lang_String *resultString; 
355         data = javastring_toutf(par2, 0);
356         
357         if (!data) {
358                 log_text("nativeGetLibName: Error: empty string");
359                 return 0;;
360         }
361         
362         buffer_len = utf_strlen(data) + 6 /*lib .so */ +1 /*0*/;
363         buffer = MNEW(char, buffer_len);
364         sprintf(buffer,"lib");
365         utf_sprint(buffer+3,data);
366         strcat(buffer,".so");
367 #ifdef JOWENN_DEBUG
368         log_text("nativeGetLibName:");
369         log_text(buffer);
370 #endif
371         
372         resultString=javastring_new_char(buffer);       
373
374         MFREE(buffer, char, buffer_len);
375         return resultString;
376 }
377
378
379 /*
380  * Class:     java_lang_VMRuntime
381  * Method:    insertSystemProperties
382  * Signature: (Ljava/util/Properties;)V
383  */
384 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_insertSystemProperties(JNIEnv *env, jclass clazz, java_util_Properties *p)
385 {
386
387 #define BUFFERSIZE 200
388         methodinfo *m;
389         char cwd[BUFFERSIZE];
390         char *java_home;
391         char *user;
392         char *home;
393         struct utsname utsnamebuf;
394
395         if (!p) {
396                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
397                 return;
398         }
399
400         /* get properties from system */
401
402         (void) getcwd(cwd, BUFFERSIZE);
403         java_home = getenv("JAVA_HOME");
404         user = getenv("USER");
405         home = getenv("HOME");
406         uname(&utsnamebuf);
407
408         /* search for method to add properties */
409
410         m = class_resolveclassmethod(p->header.vftbl->class,
411                                                                  utf_new_char("put"),
412                                                                  utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
413                                                                  clazz,
414                                                                  true);
415
416         if (!m)
417                 return;
418
419         insert_property(m, p, "java.version", VERSION);
420         insert_property(m, p, "java.vendor", "CACAO Team");
421         insert_property(m, p, "java.vendor.url", "http://www.complang.tuwien.ac.at/java/cacao/");
422         insert_property(m, p, "java.home", java_home ? java_home : "null");
423         insert_property(m, p, "java.vm.specification.version", "1.0");
424         insert_property(m, p, "java.vm.specification.vendor", "Sun Microsystems Inc.");
425         insert_property(m, p, "java.vm.specification.name", "Java Virtual Machine Specification");
426         insert_property(m, p, "java.vm.version", VERSION);
427         insert_property(m, p, "java.vm.vendor", "CACAO Team");
428         insert_property(m, p, "java.vm.name", "CACAO");
429         insert_property(m, p, "java.specification.version", "1.4");
430         insert_property(m, p, "java.specification.vendor", "Sun Microsystems Inc.");
431         insert_property(m, p, "java.specification.name", "Java Platform API Specification");
432         insert_property(m, p, "java.class.version", "48.0");
433         insert_property(m, p, "java.class.path", classpath);
434 #if defined(STATIC_CLASSPATH)
435         insert_property(m, p, "java.library.path" , ".");
436 #else
437         insert_property(m, p, "java.library.path" , getenv("LD_LIBRARY_PATH"));
438 #endif
439         insert_property(m, p, "java.io.tmpdir", "/tmp");
440         insert_property(m, p, "java.compiler", "cacao.jit");
441         insert_property(m, p, "java.ext.dirs", "null");
442         insert_property(m, p, "os.name", utsnamebuf.sysname);
443         insert_property(m, p, "os.arch", utsnamebuf.machine);
444         insert_property(m, p, "os.version", utsnamebuf.release);
445         insert_property(m, p, "file.separator", "/");
446         /* insert_property(m, p, "file.encoding", "null"); -- this must be set properly */
447         insert_property(m, p, "path.separator", ":");
448         insert_property(m, p, "line.separator", "\n");
449         insert_property(m, p, "user.name", user ? user : "null");
450         insert_property(m, p, "user.home", home ? home : "null");
451         insert_property(m, p, "user.dir", cwd ? cwd : "null");
452
453 #if 0
454         /* how do we get them? */
455         { "user.language", "en" },
456         { "user.region", "US" },
457         { "user.country", "US" },
458         { "user.timezone", "Europe/Vienna" },
459
460         /* XXX do we need this one? */
461         { "java.protocol.handler.pkgs", "gnu.java.net.protocol"}
462 #endif
463
464         /* insert properties defined on commandline */
465
466         while (properties) {
467                 property *tp;
468
469                 insert_property(m, p, properties->key, properties->value);
470
471                 tp = properties;
472                 properties = properties->next;
473                 FREE(tp, property);
474         }
475
476         return;
477 }
478
479
480 /*
481  * Class:     java_lang_VMRuntime
482  * Method:    maxMemory
483  * Signature: ()J
484  */
485 JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_maxMemory(JNIEnv *env, jclass clazz)
486 {
487         return gc_get_max_heap_size();
488 }
489
490
491 /*
492  * These are local overrides for various environment variables in Emacs.
493  * Please do not remove this and leave it at the end of the file, where
494  * Emacs will automagically detect them.
495  * ---------------------------------------------------------------------
496  * Local variables:
497  * mode: c
498  * indent-tabs-mode: t
499  * c-basic-offset: 4
500  * tab-width: 4
501  * End:
502  */