1 /* src/vm/properties.c - handling commandline properties
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33 #include <sys/utsname.h>
37 #include "mm/memory.h"
39 #include "native/jni.h"
40 #include "native/llni.h"
42 #include "vm/global.h" /* required by java_lang_String.h */
43 #include "native/include/java_lang_String.h"
45 #include "toolbox/list.h"
46 #include "toolbox/util.h"
48 #include "vm/properties.h"
49 #include "vm/stringlocal.h"
52 #include "vm/jit/asmpart.h"
54 #include "vmcore/class.h"
55 #include "vmcore/method.h"
56 #include "vmcore/options.h"
57 #include "vmcore/system.h"
60 /* internal property structure ************************************************/
62 typedef struct list_properties_entry_t list_properties_entry_t;
64 struct list_properties_entry_t {
71 /* global variables ***********************************************************/
73 static list_t *list_properties = NULL;
76 /* properties_init *************************************************************
78 Initialize the properties list and fill the list with default
81 *******************************************************************************/
83 void properties_init(void)
85 TRACESUBSYSTEMINITIALIZATION("properties_init");
87 list_properties = list_create(OFFSET(list_properties_entry_t, linkage));
91 /* properties_set **************************************************************
93 Fill the properties list with default values.
95 *******************************************************************************/
97 void properties_set(void)
103 char *boot_class_path;
105 #if defined(ENABLE_JAVASE)
107 char *boot_library_path;
111 # if defined(WITH_CLASSPATH_GNU)
118 struct utsname *utsnamebuf;
120 char *java_library_path;
124 #if defined(ENABLE_JRE_LAYOUT)
125 /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
127 p = MNEW(char, 4096);
129 if (readlink("/proc/self/exe", p, 4095) == -1)
130 vm_abort("properties_set: readlink failed: %s\n", strerror(errno));
132 /* We have a path like:
134 /path/to/executable/bin/java
138 /path/to/executeable/jre/bin/java
140 Now let's strip two levels. */
142 p = system_dirname(p);
143 p = system_dirname(p);
145 # if defined(WITH_CLASSPATH_GNU)
149 java_home = strdup(p);
151 /* Set the path to Java core native libraries. */
153 len = strlen(java_home) + strlen("/lib/classpath") + strlen("0");
155 boot_library_path = MNEW(char, len);
157 strcpy(boot_library_path, java_home);
158 strcat(boot_library_path, "/lib/classpath");
160 # elif defined(WITH_CLASSPATH_SUN)
162 /* Find correct java.home. We check if there is a JRE
165 /* NOTE: We use the server VM here as it should be available on
166 all architectures. */
170 strlen("/jre/lib/"JAVA_ARCH"/server/libjvm.so") +
173 java_home = MNEW(char, len);
175 strcpy(java_home, p);
176 strcat(java_home, "/jre/lib/"JAVA_ARCH"/server/libjvm.so");
178 /* Check if that libjvm.so exists. */
180 if (system_access(java_home, F_OK) == 0) {
181 /* Yes, we add /jre to java.home. */
183 strcpy(java_home, p);
184 strcat(java_home, "/jre");
187 /* No, java.home is parent directory. */
189 strcpy(java_home, p);
192 /* Set the path to Java core native libraries. */
194 len = strlen(java_home) + strlen("/lib/"JAVA_ARCH) + strlen("0");
196 boot_library_path = MNEW(char, len);
198 strcpy(boot_library_path, java_home);
199 strcat(boot_library_path, "/lib/"JAVA_ARCH);
202 # error unknown classpath configuration
210 java_home = CACAO_PREFIX;
212 # if defined(WITH_CLASSPATH_GNU)
214 boot_library_path = CLASSPATH_LIBDIR"/classpath";
216 # elif defined(WITH_CLASSPATH_SUN)
218 boot_library_path = CLASSPATH_LIBDIR;
220 # elif defined(WITH_CLASSPATH_CLDC1_1)
222 /* No boot_library_path required. */
225 # error unknown classpath configuration
229 properties_add("java.home", java_home);
231 /* Set the bootclasspath. */
233 p = getenv("BOOTCLASSPATH");
236 boot_class_path = MNEW(char, strlen(p) + strlen("0"));
237 strcpy(boot_class_path, p);
240 #if defined(ENABLE_JRE_LAYOUT)
241 # if defined(WITH_CLASSPATH_GNU)
244 strlen(java_home) + strlen("/share/cacao/vm.zip:") +
245 strlen(java_home) + strlen("/share/classpath/glibj.zip") +
248 boot_class_path = MNEW(char, len);
250 strcpy(boot_class_path, java_home);
251 strcat(boot_class_path, "/share/cacao/vm.zip");
252 strcat(boot_class_path, ":");
253 strcat(boot_class_path, java_home);
254 strcat(boot_class_path, "/share/classpath/glibj.zip");
256 # elif defined(WITH_CLASSPATH_SUN)
258 /* This is the bootclasspath taken from HotSpot (see
259 hotspot/src/share/vm/runtime/os.cpp
260 (os::set_boot_path)). */
263 strlen(java_home) + strlen("/lib/resources.jar:") +
264 strlen(java_home) + strlen("/lib/rt.jar:") +
265 strlen(java_home) + strlen("/lib/sunrsasign.jar:") +
266 strlen(java_home) + strlen("/lib/jsse.jar:") +
267 strlen(java_home) + strlen("/lib/jce.jar:") +
268 strlen(java_home) + strlen("/lib/charsets.jar:") +
269 strlen(java_home) + strlen("/classes") +
272 boot_class_path = MNEW(char, len);
274 strcpy(boot_class_path, java_home);
275 strcat(boot_class_path, "/lib/resources.jar:");
276 strcat(boot_class_path, java_home);
277 strcat(boot_class_path, "/lib/rt.jar:");
278 strcat(boot_class_path, java_home);
279 strcat(boot_class_path, "/lib/sunrsasign.jar:");
280 strcat(boot_class_path, java_home);
281 strcat(boot_class_path, "/lib/jsse.jar:");
282 strcat(boot_class_path, java_home);
283 strcat(boot_class_path, "/lib/jce.jar:");
284 strcat(boot_class_path, java_home);
285 strcat(boot_class_path, "/lib/charsets.jar:");
286 strcat(boot_class_path, java_home);
287 strcat(boot_class_path, "/classes");
290 # error unknown classpath configuration
293 # if defined(WITH_CLASSPATH_GNU)
296 strlen(CACAO_VM_ZIP) +
298 strlen(CLASSPATH_CLASSES) +
301 boot_class_path = MNEW(char, len);
303 strcpy(boot_class_path, CACAO_VM_ZIP);
304 strcat(boot_class_path, ":");
305 strcat(boot_class_path, CLASSPATH_CLASSES);
307 # elif defined(WITH_CLASSPATH_SUN)
309 /* This is the bootclasspath taken from HotSpot (see
310 hotspot/src/share/vm/runtime/os.cpp
311 (os::set_boot_path)). */
314 strlen(CLASSPATH_PREFIX"/lib/resources.jar:") +
315 strlen(CLASSPATH_PREFIX"/lib/rt.jar:") +
316 strlen(CLASSPATH_PREFIX"/lib/sunrsasign.jar:") +
317 strlen(CLASSPATH_PREFIX"/lib/jsse.jar:") +
318 strlen(CLASSPATH_PREFIX"/lib/jce.jar:") +
319 strlen(CLASSPATH_PREFIX"/lib/charsets.jar:") +
320 strlen(CLASSPATH_PREFIX"/classes") +
323 boot_class_path = MNEW(char, len);
325 strcpy(boot_class_path, CLASSPATH_PREFIX"/lib/resources.jar:");
326 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/rt.jar:");
327 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/sunrsasign.jar:");
328 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/jsse.jar:");
329 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/jce.jar:");
330 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/charsets.jar:");
331 strcat(boot_class_path, CLASSPATH_PREFIX"/classes");
333 # elif defined(WITH_CLASSPATH_CLDC1_1)
336 strlen(CLASSPATH_CLASSES) +
339 boot_class_path = MNEW(char, len);
341 strcpy(boot_class_path, CLASSPATH_CLASSES);
344 # error unknown classpath configuration
349 properties_add("sun.boot.class.path", boot_class_path);
350 properties_add("java.boot.class.path", boot_class_path);
352 #if defined(ENABLE_JAVASE)
354 /* Set the classpath. */
356 p = getenv("CLASSPATH");
359 class_path = MNEW(char, strlen(p) + strlen("0"));
360 strcpy(class_path, p);
363 class_path = MNEW(char, strlen(".") + strlen("0"));
364 strcpy(class_path, ".");
367 properties_add("java.class.path", class_path);
369 /* Add java.vm properties. */
371 properties_add("java.vm.specification.version", "1.0");
372 properties_add("java.vm.specification.vendor", "Sun Microsystems Inc.");
373 properties_add("java.vm.specification.name", "Java Virtual Machine Specification");
374 properties_add("java.vm.version", VERSION);
375 properties_add("java.vm.vendor", "CACAO Team");
376 properties_add("java.vm.name", "CACAO");
378 # if defined(ENABLE_INTRP)
380 /* XXX We don't support java.lang.Compiler */
381 /* properties_add("java.compiler", "cacao.intrp"); */
382 properties_add("java.vm.info", "interpreted mode");
387 /* XXX We don't support java.lang.Compiler */
388 /* properties_add("java.compiler", "cacao.jit"); */
389 properties_add("java.vm.info", "JIT mode");
392 # if defined(WITH_CLASSPATH_GNU)
394 /* Get properties from system. */
398 env_user = getenv("USER");
399 env_home = getenv("HOME");
400 env_lang = getenv("LANG");
402 utsnamebuf = NEW(struct utsname);
406 properties_add("java.runtime.version", VERSION);
407 properties_add("java.runtime.name", "CACAO");
409 properties_add("java.specification.version", "1.5");
410 properties_add("java.specification.vendor", "Sun Microsystems Inc.");
411 properties_add("java.specification.name", "Java Platform API Specification");
413 properties_add("java.version", JAVA_VERSION);
414 properties_add("java.vendor", "GNU Classpath");
415 properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/");
417 properties_add("java.class.version", CLASS_VERSION);
419 properties_add("gnu.classpath.boot.library.path", boot_library_path);
421 /* Get and set java.library.path. */
423 java_library_path = getenv("LD_LIBRARY_PATH");
425 if (java_library_path == NULL)
426 java_library_path = "";
428 properties_add("java.library.path", java_library_path);
430 properties_add("java.io.tmpdir", "/tmp");
432 # if defined(ENABLE_INTRP)
434 properties_add("gnu.java.compiler.name", "cacao.intrp");
439 properties_add("gnu.java.compiler.name", "cacao.jit");
442 /* Set the java.ext.dirs property. */
444 len = strlen(java_home) + strlen("/jre/lib/ext") + strlen("0");
446 extdirs = MNEW(char, len);
448 sprintf(extdirs, "%s/jre/lib/ext", java_home);
450 properties_add("java.ext.dirs", extdirs);
452 /* Set the java.ext.endorsed property. */
454 len = strlen(java_home) + strlen("/jre/lib/endorsed") + strlen("0");
456 endorseddirs = MNEW(char, len);
458 sprintf(endorseddirs, "%s/jre/lib/endorsed", java_home);
460 properties_add("java.endorsed.dirs", endorseddirs);
462 # if defined(DISABLE_GC)
463 /* When we disable the GC, we mmap the whole heap to a specific
464 address, so we can compare call traces. For this reason we have
465 to add the same properties on different machines, otherwise
466 more memory may be allocated (e.g. strlen("i386")
467 vs. strlen("alpha"). */
469 properties_add("os.arch", "unknown");
470 properties_add("os.name", "unknown");
471 properties_add("os.version", "unknown");
473 properties_add("os.arch", JAVA_ARCH);
474 properties_add("os.name", utsnamebuf->sysname);
475 properties_add("os.version", utsnamebuf->release);
478 # if WORDS_BIGENDIAN == 1
479 properties_add("gnu.cpu.endian", "big");
481 properties_add("gnu.cpu.endian", "little");
484 properties_add("file.separator", "/");
485 properties_add("path.separator", ":");
486 properties_add("line.separator", "\n");
488 properties_add("user.name", env_user ? env_user : "null");
489 properties_add("user.home", env_home ? env_home : "null");
490 properties_add("user.dir", cwd ? cwd : "null");
494 if (env_lang != NULL) {
495 /* get the local stuff from the environment */
497 if (strlen(env_lang) <= 2) {
498 properties_add("user.language", env_lang);
501 if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
502 lang = MNEW(char, 3);
503 strncpy(lang, (char *) &env_lang[0], 2);
506 country = MNEW(char, 3);
507 strncpy(country, (char *) &env_lang[3], 2);
510 properties_add("user.language", lang);
511 properties_add("user.country", country);
516 /* if no default locale was specified, use `en_US' */
518 properties_add("user.language", "en");
519 properties_add("user.country", "US");
522 # elif defined(WITH_CLASSPATH_SUN)
524 /* Actually this property is set by OpenJDK, but we need it in
525 nativevm_preinit(). */
527 properties_add("sun.boot.library.path", boot_library_path);
529 /* Set the java.ext.dirs property. */
532 strlen(java_home) + strlen("/lib/ext") +
534 strlen("/usr/java/packages/lib/ext") +
537 extdirs = MNEW(char, len);
539 sprintf(extdirs, "%s/lib/ext:/usr/java/packages/lib/ext", java_home);
541 properties_add("java.ext.dirs", extdirs);
543 /* Set the java.ext.endorsed property. */
545 len = strlen(java_home) + strlen("/lib/endorsed") + strlen("0");
547 endorseddirs = MNEW(char, len);
549 sprintf(endorseddirs, "%s/lib/endorsed", java_home);
551 properties_add("java.endorsed.dirs", endorseddirs);
555 # error unknown classpath configuration
559 #elif defined(ENABLE_JAVAME_CLDC1_1)
561 properties_add("microedition.configuration", "CLDC-1.1");
562 properties_add("microedition.platform", "generic");
563 properties_add("microedition.encoding", "ISO8859_1");
564 properties_add("microedition.profiles", "");
568 # error unknown Java configuration
574 /* properties_add **************************************************************
576 Adds a property entry to the internal property list. If there's
577 already an entry with the same key, replace it.
579 *******************************************************************************/
581 void properties_add(char *key, char *value)
583 list_properties_entry_t *pe;
585 /* search for the entry */
587 for (pe = list_first(list_properties); pe != NULL;
588 pe = list_next(list_properties, pe)) {
589 if (strcmp(pe->key, key) == 0) {
590 /* entry was found, replace the value */
593 if (opt_DebugProperties) {
594 printf("[properties_add: key=%s, old value=%s, new value=%s]\n",
595 key, pe->value, value);
605 /* entry was not found, insert a new one */
608 if (opt_DebugProperties) {
609 printf("[properties_add: key=%s, value=%s]\n", key, value);
613 pe = NEW(list_properties_entry_t);
618 list_add_last(list_properties, pe);
622 /* properties_get **************************************************************
624 Get a property entry from the internal property list.
626 *******************************************************************************/
628 char *properties_get(char *key)
630 list_properties_entry_t *pe;
632 for (pe = list_first(list_properties); pe != NULL;
633 pe = list_next(list_properties, pe)) {
634 if (strcmp(pe->key, key) == 0)
642 /* properties_system_add *******************************************************
644 Adds a given property to the Java system properties.
646 *******************************************************************************/
648 void properties_system_add(java_handle_t *p, char *key, char *value)
655 /* search for method to add properties */
657 LLNI_class_get(p, c);
659 m = class_resolveclassmethod(c,
661 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
668 /* add to the Java system properties */
670 k = javastring_new_from_utf_string(key);
671 v = javastring_new_from_utf_string(value);
673 (void) vm_call_method(m, p, k, v);
677 /* properties_system_add_all ***************************************************
679 Adds all properties from the properties list to the Java system
683 p.... is actually a java_util_Properties structure
685 *******************************************************************************/
687 #if defined(ENABLE_JAVASE)
688 void properties_system_add_all(java_handle_t *p)
690 list_properties_entry_t *pe;
694 java_handle_t *value;
696 /* search for method to add properties */
698 LLNI_class_get(p, c);
700 m = class_resolveclassmethod(c,
702 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
709 /* process all properties stored in the internal table */
711 for (pe = list_first(list_properties); pe != NULL;
712 pe = list_next(list_properties, pe)) {
713 /* add to the Java system properties */
715 key = javastring_new_from_utf_string(pe->key);
716 value = javastring_new_from_utf_string(pe->value);
718 (void) vm_call_method(m, (java_handle_t *) p, key, value);
721 #endif /* defined(ENABLE_JAVASE) */
724 /* properties_dump *************************************************************
726 Dump all property entries.
728 *******************************************************************************/
730 void properties_dump(void)
733 list_properties_entry_t *pe;
735 /* For convenience. */
739 for (pe = list_first(l); pe != NULL; pe = list_next(l, pe)) {
740 log_println("[properties_dump: key=%s, value=%s]", pe->key, pe->value);
746 * These are local overrides for various environment variables in Emacs.
747 * Please do not remove this and leave it at the end of the file, where
748 * Emacs will automagically detect them.
749 * ---------------------------------------------------------------------
752 * indent-tabs-mode: t