* src/vm/properties.c (properties_init) [WITH_CLASSPATH_SUN]: Removed
[cacao.git] / src / vm / properties.c
1 /* src/vm/properties.c - handling commandline properties
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: properties.c 8382 2007-08-21 13:05:42Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <time.h>
35 #include <unistd.h>
36 #include <sys/utsname.h>
37
38 #include "vm/types.h"
39
40 #include "mm/memory.h"
41
42 #include "native/jni.h"
43
44 #include "vm/global.h"                      /* required by java_lang_String.h */
45 #include "native/include/java_lang_String.h"
46
47 #include "toolbox/list.h"
48 #include "toolbox/util.h"
49
50 #include "vm/properties.h"
51 #include "vm/stringlocal.h"
52 #include "vm/vm.h"
53
54 #include "vm/jit/asmpart.h"
55
56 #include "vmcore/method.h"
57 #include "vmcore/options.h"
58
59
60 /* internal property structure ************************************************/
61
62 typedef struct list_properties_entry list_properties_entry;
63
64 struct list_properties_entry {
65         char       *key;
66         char       *value;
67         listnode_t  linkage;
68 };
69
70
71 /* global variables ***********************************************************/
72
73 static list_t *list_properties = NULL;
74
75
76 /* properties_init *************************************************************
77
78    Initialize the properties list and fill the list with default
79    values.
80
81 *******************************************************************************/
82
83 bool properties_init(void)
84 {
85 #if defined(ENABLE_JAVASE)
86         char           *env_java_home;
87         char           *java_home;
88         s4              len;
89
90 # if defined(WITH_CLASSPATH_GNU)
91         char           *cwd;
92         char           *env_user;
93         char           *env_home;
94         char           *env_lang;
95         char           *extdirs;
96         char           *lang;
97         char           *country;
98         struct utsname *utsnamebuf;
99 # endif
100 #endif
101
102         /* create the properties list */
103
104         list_properties = list_create(OFFSET(list_properties_entry, linkage));
105
106 #if defined(ENABLE_JAVASE)
107
108         /* get properties from system */
109
110         env_java_home = getenv("JAVA_HOME");
111
112         /* set JAVA_HOME to default prefix if not defined */
113
114         if (env_java_home == NULL)
115                 env_java_home = cacao_prefix;
116
117         /* fill in system properties */
118
119         /* add /jre to java.home property */
120
121         len = strlen(env_java_home) + strlen("/jre") + strlen("0");
122
123         java_home = MNEW(char, len);
124
125         strcpy(java_home, env_java_home);
126         strcat(java_home, "/jre");
127
128         properties_add("java.home", java_home);
129
130         properties_add("java.vm.specification.version", "1.0");
131         properties_add("java.vm.specification.vendor", "Sun Microsystems Inc.");
132         properties_add("java.vm.specification.name", "Java Virtual Machine Specification");
133         properties_add("java.vm.version", VERSION);
134         properties_add("java.vm.vendor", "CACAO Team");
135         properties_add("java.vm.name", "CACAO");
136
137 # if defined(ENABLE_INTRP)
138         if (opt_intrp) {
139                 /* XXX We don't support java.lang.Compiler */
140 /*              properties_add("java.compiler", "cacao.intrp"); */
141                 properties_add("java.vm.info", "interpreted mode");
142         }
143         else
144 # endif
145         {
146                 /* XXX We don't support java.lang.Compiler */
147 /*              properties_add("java.compiler", "cacao.jit"); */
148                 properties_add("java.vm.info", "JIT mode");
149         }
150
151 # if defined(WITH_CLASSPATH_GNU)
152
153         /* get properties from system */
154
155         cwd      = _Jv_getcwd();
156
157         env_user = getenv("USER");
158         env_home = getenv("HOME");
159         env_lang = getenv("LANG");
160
161         utsnamebuf = NEW(struct utsname);
162
163         uname(utsnamebuf);
164
165         properties_add("java.runtime.version", VERSION);
166         properties_add("java.runtime.name", "CACAO");
167
168         properties_add("java.specification.version", "1.5");
169         properties_add("java.specification.vendor", "Sun Microsystems Inc.");
170         properties_add("java.specification.name", "Java Platform API Specification");
171
172         properties_add("java.version", JAVA_VERSION);
173         properties_add("java.vendor", "GNU Classpath");
174         properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/");
175
176         properties_add("java.class.path", _Jv_classpath);
177         properties_add("java.class.version", CLASS_VERSION);
178
179         /* Set bootclasspath properties. One for GNU classpath and the
180            other for compatibility with Sun (required by most
181            applications). */
182
183         properties_add("java.boot.class.path", _Jv_bootclasspath);
184         properties_add("sun.boot.class.path", _Jv_bootclasspath);
185
186 #  if defined(WITH_STATIC_CLASSPATH)
187         properties_add("gnu.classpath.boot.library.path", ".");
188         properties_add("java.library.path" , ".");
189 #  else
190         /* fill gnu.classpath.boot.library.path with GNU Classpath library
191        path */
192
193         properties_add("gnu.classpath.boot.library.path", classpath_libdir);
194         properties_add("java.library.path", _Jv_java_library_path);
195 #  endif
196
197         properties_add("java.io.tmpdir", "/tmp");
198
199 #  if defined(ENABLE_INTRP)
200         if (opt_intrp) {
201                 properties_add("gnu.java.compiler.name", "cacao.intrp");
202         }
203         else
204 #  endif
205         {
206                 properties_add("gnu.java.compiler.name", "cacao.jit");
207         }
208
209         /* set the java.ext.dirs property */
210
211         len = strlen(env_java_home) + strlen("/jre/lib/ext") + strlen("0");
212
213         extdirs = MNEW(char, len);
214
215         strcpy(extdirs, env_java_home);
216         strcat(extdirs, "/jre/lib/ext");
217
218         properties_add("java.ext.dirs", extdirs);
219
220         properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed");
221
222 #  if defined(DISABLE_GC)
223         /* When we disable the GC, we mmap the whole heap to a specific
224            address, so we can compare call traces. For this reason we have
225            to add the same properties on different machines, otherwise
226            more memory may be allocated (e.g. strlen("i386")
227            vs. strlen("alpha"). */
228
229         properties_add("os.arch", "unknown");
230         properties_add("os.name", "unknown");
231         properties_add("os.version", "unknown");
232 #  else
233         properties_add("os.arch", JAVA_ARCH);
234         properties_add("os.name", utsnamebuf->sysname);
235         properties_add("os.version", utsnamebuf->release);
236 #  endif
237
238 #  if defined(WITH_STATIC_CLASSPATH)
239         /* This is just for debugging purposes and can cause troubles in
240        GNU Classpath. */
241
242         properties_add("gnu.cpu.endian", "unknown");
243 #  else
244 #   if WORDS_BIGENDIAN == 1
245         properties_add("gnu.cpu.endian", "big");
246 #   else
247         properties_add("gnu.cpu.endian", "little");
248 #   endif
249 #  endif
250
251         properties_add("file.separator", "/");
252         properties_add("path.separator", ":");
253         properties_add("line.separator", "\n");
254
255         properties_add("user.name", env_user ? env_user : "null");
256         properties_add("user.home", env_home ? env_home : "null");
257         properties_add("user.dir", cwd ? cwd : "null");
258
259         /* get locale */
260
261         if (env_lang != NULL) {
262                 /* get the local stuff from the environment */
263
264                 if (strlen(env_lang) <= 2) {
265                         properties_add("user.language", env_lang);
266                 }
267                 else {
268                         if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
269                                 lang = MNEW(char, 3);
270                                 strncpy(lang, (char *) &env_lang[0], 2);
271                                 lang[2] = '\0';
272
273                                 country = MNEW(char, 3);
274                                 strncpy(country, (char *) &env_lang[3], 2);
275                                 country[2] = '\0';
276
277                                 properties_add("user.language", lang);
278                                 properties_add("user.country", country);
279                         }
280                 }
281         }
282         else {
283                 /* if no default locale was specified, use `en_US' */
284
285                 properties_add("user.language", "en");
286                 properties_add("user.country", "US");
287         }
288
289 # elif defined(WITH_CLASSPATH_SUN)
290
291         /* Find correct java.home.  We check if there is a JRE
292            co-located. */
293
294         /* NOTE: We use the server VM here as it should be available on
295            all architectures. */
296
297         len =
298                 strlen(env_java_home) +
299                 strlen("/jre/lib/"JAVA_ARCH"/server/libjvm.so") +
300                 strlen("0");
301
302         java_home = MNEW(char, len);
303
304         strcpy(java_home, env_java_home);
305         strcat(java_home, "/jre/lib/"JAVA_ARCH"/server/libjvm.so");
306
307         /* Check if that libjvm.so exists. */
308
309         if (access(java_home, F_OK) == 0) {
310                 /* Yes, we add /jre to java.home. */
311
312                 strcpy(java_home, env_java_home);
313                 strcat(java_home, "/jre");
314         }
315         else {
316                 /* No, java.home is at it is. */
317
318                 strcpy(java_home, env_java_home);
319         }
320
321         properties_add("java.home", java_home);
322         properties_add("sun.boot.library.path", classpath_libdir);
323
324 # else
325
326 #  error unknown classpath configuration
327
328 # endif
329
330 #elif defined(ENABLE_JAVAME_CLDC1_1)
331
332     properties_add("microedition.configuration", "CLDC-1.1");
333     properties_add("microedition.platform", "generic");
334     properties_add("microedition.encoding", "ISO8859_1");
335     properties_add("microedition.profiles", "");
336
337 #else
338
339 # error unknown Java configuration
340
341 #endif
342
343         /* everything's ok */
344
345         return true;
346 }
347
348
349 /* properties_add **************************************************************
350
351    Adds a property entry to the internal property list.  If there's
352    already an entry with the same key, replace it.
353
354 *******************************************************************************/
355
356 void properties_add(char *key, char *value)
357 {
358         list_properties_entry *pe;
359
360         /* search for the entry */
361
362         for (pe = list_first_unsynced(list_properties); pe != NULL;
363                  pe = list_next_unsynced(list_properties, pe)) {
364                 if (strcmp(pe->key, key) == 0) {
365                         /* entry was found, replace the value */
366
367                         pe->value = value;
368
369                         return;
370                 }
371         }
372
373         /* entry was not found, insert a new one */
374
375         pe = NEW(list_properties_entry);
376
377         pe->key   = key;
378         pe->value = value;
379
380         list_add_last_unsynced(list_properties, pe);
381 }
382
383
384 /* properties_get **************************************************************
385
386    Get a property entry from the internal property list.
387
388 *******************************************************************************/
389
390 char *properties_get(char *key)
391 {
392         list_properties_entry *pe;
393
394         for (pe = list_first_unsynced(list_properties); pe != NULL;
395                  pe = list_next_unsynced(list_properties, pe)) {
396                 if (strcmp(pe->key, key) == 0)
397                         return pe->value;
398         }
399
400         return NULL;
401 }
402
403
404 /* properties_system_add *******************************************************
405
406    Adds a given property to the Java system properties.
407
408 *******************************************************************************/
409
410 void properties_system_add(java_handle_t *p, char *key, char *value)
411 {
412         methodinfo    *m;
413         java_handle_t *k;
414         java_handle_t *v;
415
416         /* search for method to add properties */
417
418         m = class_resolveclassmethod(p->vftbl->class,
419                                                                  utf_put,
420                                                                  utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
421                                                                  NULL,
422                                                                  true);
423
424         if (m == NULL)
425                 return;
426
427         /* add to the Java system properties */
428
429         k = javastring_new_from_utf_string(key);
430         v = javastring_new_from_utf_string(value);
431
432         (void) vm_call_method(m, p, k, v);
433 }
434
435
436 /* properties_system_add_all ***************************************************
437
438    Adds all properties from the properties list to the Java system
439    properties.
440
441    ARGUMENTS:
442        p.... is actually a java_util_Properties structure
443
444 *******************************************************************************/
445
446 #if defined(ENABLE_JAVASE)
447 void properties_system_add_all(java_handle_t *p)
448 {
449         list_properties_entry *pe;
450         methodinfo            *m;
451         java_handle_t         *key;
452         java_handle_t         *value;
453
454         /* search for method to add properties */
455
456         m = class_resolveclassmethod(p->vftbl->class,
457                                                                  utf_put,
458                                                                  utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
459                                                                  NULL,
460                                                                  true);
461
462         if (m == NULL)
463                 return;
464
465         /* process all properties stored in the internal table */
466
467         for (pe = list_first(list_properties); pe != NULL;
468                  pe = list_next(list_properties, pe)) {
469                 /* add to the Java system properties */
470
471                 key   = javastring_new_from_utf_string(pe->key);
472                 value = javastring_new_from_utf_string(pe->value);
473
474                 (void) vm_call_method(m, (java_handle_t *) p, key, value);
475         }
476 }
477 #endif /* defined(ENABLE_JAVASE) */
478
479
480 /*
481  * These are local overrides for various environment variables in Emacs.
482  * Please do not remove this and leave it at the end of the file, where
483  * Emacs will automagically detect them.
484  * ---------------------------------------------------------------------
485  * Local variables:
486  * mode: c
487  * indent-tabs-mode: t
488  * c-basic-offset: 4
489  * tab-width: 4
490  * End:
491  */