1 /* src/vm/properties.c - handling commandline properties
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
8 This file is part of CACAO.
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.
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.
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
35 #include <sys/utsname.h>
37 #if defined(WITH_JRE_LAYOUT)
43 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/llni.h"
48 #include "vm/global.h" /* required by java_lang_String.h */
49 #include "native/include/java_lang_String.h"
51 #include "toolbox/list.h"
52 #include "toolbox/util.h"
54 #include "vm/properties.h"
55 #include "vm/stringlocal.h"
58 #include "vm/jit/asmpart.h"
60 #include "vmcore/class.h"
61 #include "vmcore/method.h"
62 #include "vmcore/options.h"
65 /* internal property structure ************************************************/
67 typedef struct list_properties_entry_t list_properties_entry_t;
69 struct list_properties_entry_t {
76 /* global variables ***********************************************************/
78 static list_t *list_properties = NULL;
81 /* properties_init *************************************************************
83 Initialize the properties list and fill the list with default
86 *******************************************************************************/
88 void properties_init(void)
90 list_properties = list_create(OFFSET(list_properties_entry_t, linkage));
94 /* properties_set **************************************************************
96 Fill the properties list with default values.
98 *******************************************************************************/
100 void properties_set(void)
106 char *boot_class_path;
108 #if defined(ENABLE_JAVASE)
110 char *boot_library_path;
114 # if defined(WITH_CLASSPATH_GNU)
121 struct utsname *utsnamebuf;
123 char *java_library_path;
127 #if defined(WITH_JRE_LAYOUT)
128 /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
130 p = MNEW(char, 4096);
132 if (readlink("/proc/self/exe", p, 4095) == -1)
133 vm_abort("properties_set: readlink failed: %s\n", strerror(errno));
135 /* We have a path like:
137 /path/to/executable/bin/java
141 /path/to/executeable/jre/bin/java
143 Now let's strip two levels. */
148 # if defined(WITH_CLASSPATH_GNU)
152 java_home = strdup(p);
154 /* Set the path to Java core native libraries. */
156 len = strlen(java_home) + strlen("/lib/classpath") + strlen("0");
158 boot_library_path = MNEW(char, len);
160 strcpy(boot_library_path, java_home);
161 strcat(boot_library_path, "/lib/classpath");
163 # elif defined(WITH_CLASSPATH_SUN)
165 /* Find correct java.home. We check if there is a JRE
168 /* NOTE: We use the server VM here as it should be available on
169 all architectures. */
173 strlen("/jre/lib/"JAVA_ARCH"/server/libjvm.so") +
176 java_home = MNEW(char, len);
178 strcpy(java_home, p);
179 strcat(java_home, "/jre/lib/"JAVA_ARCH"/server/libjvm.so");
181 /* Check if that libjvm.so exists. */
183 if (access(java_home, F_OK) == 0) {
184 /* Yes, we add /jre to java.home. */
186 strcpy(java_home, p);
187 strcat(java_home, "/jre");
190 /* No, java.home is parent directory. */
192 strcpy(java_home, p);
195 /* Set the path to Java core native libraries. */
197 len = strlen(java_home) + strlen("/lib/"JAVA_ARCH) + strlen("0");
199 boot_library_path = MNEW(char, len);
201 strcpy(boot_library_path, java_home);
202 strcat(boot_library_path, "/lib/"JAVA_ARCH);
205 # error unknown classpath configuration
213 java_home = CACAO_PREFIX;
215 # if defined(WITH_CLASSPATH_GNU)
217 boot_library_path = CLASSPATH_LIBDIR"/classpath";
219 # elif defined(WITH_CLASSPATH_SUN)
221 boot_library_path = CLASSPATH_LIBDIR;
223 # elif defined(WITH_CLASSPATH_CLDC1_1)
225 /* No boot_library_path required. */
228 # error unknown classpath configuration
232 properties_add("java.home", java_home);
234 /* Set the bootclasspath. */
236 p = getenv("BOOTCLASSPATH");
239 boot_class_path = MNEW(char, strlen(p) + strlen("0"));
240 strcpy(boot_class_path, p);
243 #if defined(WITH_JRE_LAYOUT)
244 # if defined(WITH_CLASSPATH_GNU)
247 strlen(java_home) + strlen("/share/cacao/vm.zip:") +
248 strlen(java_home) + strlen("/share/classpath/glibj.zip") +
251 boot_class_path = MNEW(char, len);
253 strcpy(boot_class_path, java_home);
254 strcat(boot_class_path, "/share/cacao/vm.zip");
255 strcat(boot_class_path, ":");
256 strcat(boot_class_path, java_home);
257 strcat(boot_class_path, "/share/classpath/glibj.zip");
259 # elif defined(WITH_CLASSPATH_SUN)
261 /* This is the bootclasspath taken from HotSpot (see
262 hotspot/src/share/vm/runtime/os.cpp
263 (os::set_boot_path)). */
266 strlen(java_home) + strlen("/lib/resources.jar:") +
267 strlen(java_home) + strlen("/lib/rt.jar:") +
268 strlen(java_home) + strlen("/lib/sunrsasign.jar:") +
269 strlen(java_home) + strlen("/lib/jsse.jar:") +
270 strlen(java_home) + strlen("/lib/jce.jar:") +
271 strlen(java_home) + strlen("/lib/charsets.jar:") +
272 strlen(java_home) + strlen("/classes") +
275 boot_class_path = MNEW(char, len);
277 strcpy(boot_class_path, java_home);
278 strcat(boot_class_path, "/lib/resources.jar:");
279 strcat(boot_class_path, java_home);
280 strcat(boot_class_path, "/lib/rt.jar:");
281 strcat(boot_class_path, java_home);
282 strcat(boot_class_path, "/lib/sunrsasign.jar:");
283 strcat(boot_class_path, java_home);
284 strcat(boot_class_path, "/lib/jsse.jar:");
285 strcat(boot_class_path, java_home);
286 strcat(boot_class_path, "/lib/jce.jar:");
287 strcat(boot_class_path, java_home);
288 strcat(boot_class_path, "/lib/charsets.jar:");
289 strcat(boot_class_path, java_home);
290 strcat(boot_class_path, "/classes");
293 # error unknown classpath configuration
296 # if defined(WITH_CLASSPATH_GNU)
299 strlen(CACAO_VM_ZIP) +
301 strlen(CLASSPATH_CLASSES) +
304 boot_class_path = MNEW(char, len);
306 strcpy(boot_class_path, CACAO_VM_ZIP);
307 strcat(boot_class_path, ":");
308 strcat(boot_class_path, CLASSPATH_CLASSES);
310 # elif defined(WITH_CLASSPATH_SUN)
312 /* This is the bootclasspath taken from HotSpot (see
313 hotspot/src/share/vm/runtime/os.cpp
314 (os::set_boot_path)). */
317 strlen(CLASSPATH_PREFIX"/lib/resources.jar:") +
318 strlen(CLASSPATH_PREFIX"/lib/rt.jar:") +
319 strlen(CLASSPATH_PREFIX"/lib/sunrsasign.jar:") +
320 strlen(CLASSPATH_PREFIX"/lib/jsse.jar:") +
321 strlen(CLASSPATH_PREFIX"/lib/jce.jar:") +
322 strlen(CLASSPATH_PREFIX"/lib/charsets.jar:") +
323 strlen(CLASSPATH_PREFIX"/classes") +
326 boot_class_path = MNEW(char, len);
328 strcpy(boot_class_path, CLASSPATH_PREFIX"/lib/resources.jar:");
329 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/rt.jar:");
330 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/sunrsasign.jar:");
331 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/jsse.jar:");
332 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/jce.jar:");
333 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/charsets.jar:");
334 strcat(boot_class_path, CLASSPATH_PREFIX"/classes");
336 # elif defined(WITH_CLASSPATH_CLDC1_1)
339 strlen(CLASSPATH_CLASSES) +
342 boot_class_path = MNEW(char, len);
344 strcpy(boot_class_path, CLASSPATH_CLASSES);
347 # error unknown classpath configuration
352 properties_add("sun.boot.class.path", boot_class_path);
353 properties_add("java.boot.class.path", boot_class_path);
355 #if defined(ENABLE_JAVASE)
357 /* Set the classpath. */
359 p = getenv("CLASSPATH");
362 class_path = MNEW(char, strlen(p) + strlen("0"));
363 strcpy(class_path, p);
366 class_path = MNEW(char, strlen(".") + strlen("0"));
367 strcpy(class_path, ".");
370 properties_add("java.class.path", class_path);
372 /* Add java.vm properties. */
374 properties_add("java.vm.specification.version", "1.0");
375 properties_add("java.vm.specification.vendor", "Sun Microsystems Inc.");
376 properties_add("java.vm.specification.name", "Java Virtual Machine Specification");
377 properties_add("java.vm.version", VERSION);
378 properties_add("java.vm.vendor", "CACAO Team");
379 properties_add("java.vm.name", "CACAO");
381 # if defined(ENABLE_INTRP)
383 /* XXX We don't support java.lang.Compiler */
384 /* properties_add("java.compiler", "cacao.intrp"); */
385 properties_add("java.vm.info", "interpreted mode");
390 /* XXX We don't support java.lang.Compiler */
391 /* properties_add("java.compiler", "cacao.jit"); */
392 properties_add("java.vm.info", "JIT mode");
395 # if defined(WITH_CLASSPATH_GNU)
397 /* Get properties from system. */
401 env_user = getenv("USER");
402 env_home = getenv("HOME");
403 env_lang = getenv("LANG");
405 utsnamebuf = NEW(struct utsname);
409 properties_add("java.runtime.version", VERSION);
410 properties_add("java.runtime.name", "CACAO");
412 properties_add("java.specification.version", "1.5");
413 properties_add("java.specification.vendor", "Sun Microsystems Inc.");
414 properties_add("java.specification.name", "Java Platform API Specification");
416 properties_add("java.version", JAVA_VERSION);
417 properties_add("java.vendor", "GNU Classpath");
418 properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/");
420 properties_add("java.class.version", CLASS_VERSION);
422 properties_add("gnu.classpath.boot.library.path", boot_library_path);
424 /* Get and set java.library.path. */
426 java_library_path = getenv("LD_LIBRARY_PATH");
428 if (java_library_path == NULL)
429 java_library_path = "";
431 properties_add("java.library.path", java_library_path);
433 properties_add("java.io.tmpdir", "/tmp");
435 # if defined(ENABLE_INTRP)
437 properties_add("gnu.java.compiler.name", "cacao.intrp");
442 properties_add("gnu.java.compiler.name", "cacao.jit");
445 /* Set the java.ext.dirs property. */
447 len = strlen(java_home) + strlen("/jre/lib/ext") + strlen("0");
449 extdirs = MNEW(char, len);
451 sprintf(extdirs, "%s/jre/lib/ext", java_home);
453 properties_add("java.ext.dirs", extdirs);
455 /* Set the java.ext.endorsed property. */
457 len = strlen(java_home) + strlen("/jre/lib/endorsed") + strlen("0");
459 endorseddirs = MNEW(char, len);
461 sprintf(endorseddirs, "%s/jre/lib/endorsed", java_home);
463 properties_add("java.endorsed.dirs", endorseddirs);
465 # if defined(DISABLE_GC)
466 /* When we disable the GC, we mmap the whole heap to a specific
467 address, so we can compare call traces. For this reason we have
468 to add the same properties on different machines, otherwise
469 more memory may be allocated (e.g. strlen("i386")
470 vs. strlen("alpha"). */
472 properties_add("os.arch", "unknown");
473 properties_add("os.name", "unknown");
474 properties_add("os.version", "unknown");
476 properties_add("os.arch", JAVA_ARCH);
477 properties_add("os.name", utsnamebuf->sysname);
478 properties_add("os.version", utsnamebuf->release);
481 # if WORDS_BIGENDIAN == 1
482 properties_add("gnu.cpu.endian", "big");
484 properties_add("gnu.cpu.endian", "little");
487 properties_add("file.separator", "/");
488 properties_add("path.separator", ":");
489 properties_add("line.separator", "\n");
491 properties_add("user.name", env_user ? env_user : "null");
492 properties_add("user.home", env_home ? env_home : "null");
493 properties_add("user.dir", cwd ? cwd : "null");
497 if (env_lang != NULL) {
498 /* get the local stuff from the environment */
500 if (strlen(env_lang) <= 2) {
501 properties_add("user.language", env_lang);
504 if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
505 lang = MNEW(char, 3);
506 strncpy(lang, (char *) &env_lang[0], 2);
509 country = MNEW(char, 3);
510 strncpy(country, (char *) &env_lang[3], 2);
513 properties_add("user.language", lang);
514 properties_add("user.country", country);
519 /* if no default locale was specified, use `en_US' */
521 properties_add("user.language", "en");
522 properties_add("user.country", "US");
525 # elif defined(WITH_CLASSPATH_SUN)
527 /* Actually this property is set by OpenJDK, but we need it in
528 nativevm_preinit(). */
530 properties_add("sun.boot.library.path", boot_library_path);
532 /* Set the java.ext.dirs property. */
535 strlen(java_home) + strlen("/lib/ext") +
537 strlen("/usr/java/packages/lib/ext") +
540 extdirs = MNEW(char, len);
542 sprintf(extdirs, "%s/lib/ext:/usr/java/packages/lib/ext", java_home);
544 properties_add("java.ext.dirs", extdirs);
546 /* Set the java.ext.endorsed property. */
548 len = strlen(java_home) + strlen("/lib/endorsed") + strlen("0");
550 endorseddirs = MNEW(char, len);
552 sprintf(endorseddirs, "%s/lib/endorsed", java_home);
554 properties_add("java.endorsed.dirs", endorseddirs);
558 # error unknown classpath configuration
562 #elif defined(ENABLE_JAVAME_CLDC1_1)
564 properties_add("microedition.configuration", "CLDC-1.1");
565 properties_add("microedition.platform", "generic");
566 properties_add("microedition.encoding", "ISO8859_1");
567 properties_add("microedition.profiles", "");
571 # error unknown Java configuration
577 /* properties_add **************************************************************
579 Adds a property entry to the internal property list. If there's
580 already an entry with the same key, replace it.
582 *******************************************************************************/
584 void properties_add(char *key, char *value)
586 list_properties_entry_t *pe;
588 /* search for the entry */
590 for (pe = list_first_unsynced(list_properties); pe != NULL;
591 pe = list_next_unsynced(list_properties, pe)) {
592 if (strcmp(pe->key, key) == 0) {
593 /* entry was found, replace the value */
596 if (opt_DebugProperties) {
597 printf("[properties_add: key=%s, old value=%s, new value=%s]\n",
598 key, pe->value, value);
608 /* entry was not found, insert a new one */
611 if (opt_DebugProperties) {
612 printf("[properties_add: key=%s, value=%s]\n", key, value);
616 pe = NEW(list_properties_entry_t);
621 list_add_last_unsynced(list_properties, pe);
625 /* properties_get **************************************************************
627 Get a property entry from the internal property list.
629 *******************************************************************************/
631 char *properties_get(char *key)
633 list_properties_entry_t *pe;
635 for (pe = list_first_unsynced(list_properties); pe != NULL;
636 pe = list_next_unsynced(list_properties, pe)) {
637 if (strcmp(pe->key, key) == 0)
645 /* properties_system_add *******************************************************
647 Adds a given property to the Java system properties.
649 *******************************************************************************/
651 void properties_system_add(java_handle_t *p, char *key, char *value)
658 /* search for method to add properties */
660 LLNI_class_get(p, c);
662 m = class_resolveclassmethod(c,
664 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
671 /* add to the Java system properties */
673 k = javastring_new_from_utf_string(key);
674 v = javastring_new_from_utf_string(value);
676 (void) vm_call_method(m, p, k, v);
680 /* properties_system_add_all ***************************************************
682 Adds all properties from the properties list to the Java system
686 p.... is actually a java_util_Properties structure
688 *******************************************************************************/
690 #if defined(ENABLE_JAVASE)
691 void properties_system_add_all(java_handle_t *p)
693 list_properties_entry_t *pe;
697 java_handle_t *value;
699 /* search for method to add properties */
701 LLNI_class_get(p, c);
703 m = class_resolveclassmethod(c,
705 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
712 /* process all properties stored in the internal table */
714 for (pe = list_first(list_properties); pe != NULL;
715 pe = list_next(list_properties, pe)) {
716 /* add to the Java system properties */
718 key = javastring_new_from_utf_string(pe->key);
719 value = javastring_new_from_utf_string(pe->value);
721 (void) vm_call_method(m, (java_handle_t *) p, key, value);
724 #endif /* defined(ENABLE_JAVASE) */
727 /* properties_dump *************************************************************
729 Dump all property entries.
731 *******************************************************************************/
733 void properties_dump(void)
736 list_properties_entry_t *pe;
740 for (pe = list_first_unsynced(l); pe != NULL;
741 pe = list_next_unsynced(l, pe)) {
742 log_println("[properties_dump: key=%s, value=%s]", pe->key, pe->value);
748 * These are local overrides for various environment variables in Emacs.
749 * Please do not remove this and leave it at the end of the file, where
750 * Emacs will automagically detect them.
751 * ---------------------------------------------------------------------
754 * indent-tabs-mode: t