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;
112 # if defined(WITH_CLASSPATH_GNU)
120 struct utsname *utsnamebuf;
122 char *java_library_path;
126 #if defined(WITH_JRE_LAYOUT)
127 /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
129 p = MNEW(char, 4096);
131 if (readlink("/proc/self/exe", p, 4095) == -1)
132 vm_abort("properties_set: readlink failed: %s\n", strerror(errno));
134 /* Get the path of the current executable. */
138 # if defined(WITH_CLASSPATH_GNU)
142 len = strlen(p) + strlen("/..") + strlen("0");
144 java_home = MNEW(char, len);
146 strcpy(java_home, p);
147 strcat(java_home, "/..");
149 /* Set the path to Java core native libraries. */
151 len = strlen(java_home) + strlen("/lib/classpath") + strlen("0");
153 boot_library_path = MNEW(char, len);
155 strcpy(boot_library_path, java_home);
156 strcat(boot_library_path, "/lib/classpath");
158 # elif defined(WITH_CLASSPATH_SUN)
160 /* Find correct java.home. We check if there is a JRE
163 /* NOTE: We use the server VM here as it should be available on
164 all architectures. */
168 strlen("/../jre/lib/"JAVA_ARCH"/server/libjvm.so") +
171 java_home = MNEW(char, len);
173 strcpy(java_home, p);
174 strcat(java_home, "/../jre/lib/"JAVA_ARCH"/server/libjvm.so");
176 /* Check if that libjvm.so exists. */
178 if (access(java_home, F_OK) == 0) {
179 /* Yes, we add /jre to java.home. */
181 strcpy(java_home, p);
182 strcat(java_home, "/../jre");
185 /* No, java.home is parent directory. */
187 strcpy(java_home, p);
188 strcat(java_home, "/..");
191 /* Set the path to Java core native libraries. */
193 len = strlen(java_home) + strlen("/lib/"JAVA_ARCH) + strlen("0");
195 boot_library_path = MNEW(char, len);
197 strcpy(boot_library_path, java_home);
198 strcat(boot_library_path, "/lib/"JAVA_ARCH);
201 # error unknown classpath configuration
209 java_home = CACAO_PREFIX;
211 # if defined(WITH_CLASSPATH_GNU)
213 boot_library_path = CLASSPATH_LIBDIR"/classpath";
215 # elif defined(WITH_CLASSPATH_SUN)
217 boot_library_path = CLASSPATH_LIBDIR;
219 # elif defined(WITH_CLASSPATH_CLDC1_1)
221 /* No boot_library_path required. */
224 # error unknown classpath configuration
228 properties_add("java.home", java_home);
230 /* Set the bootclasspath. */
232 p = getenv("BOOTCLASSPATH");
235 boot_class_path = MNEW(char, strlen(p) + strlen("0"));
236 strcpy(boot_class_path, p);
239 #if defined(WITH_JRE_LAYOUT)
240 # if defined(WITH_CLASSPATH_GNU)
243 strlen(java_home) + strlen("/share/cacao/vm.zip:") +
244 strlen(java_home) + strlen("/share/classpath/glibj.zip") +
247 boot_class_path = MNEW(char, len);
249 strcpy(boot_class_path, java_home);
250 strcat(boot_class_path, "/share/cacao/vm.zip");
251 strcat(boot_class_path, ":");
252 strcat(boot_class_path, java_home);
253 strcat(boot_class_path, "/share/classpath/glibj.zip");
255 # elif defined(WITH_CLASSPATH_SUN)
257 /* This is the bootclasspath taken from HotSpot (see
258 hotspot/src/share/vm/runtime/os.cpp
259 (os::set_boot_path)). */
262 strlen(java_home) + strlen("/lib/resources.jar:") +
263 strlen(java_home) + strlen("/lib/rt.jar:") +
264 strlen(java_home) + strlen("/lib/sunrsasign.jar:") +
265 strlen(java_home) + strlen("/lib/jsse.jar:") +
266 strlen(java_home) + strlen("/lib/jce.jar:") +
267 strlen(java_home) + strlen("/lib/charsets.jar:") +
268 strlen(java_home) + strlen("/classes") +
271 boot_class_path = MNEW(char, len);
273 strcpy(boot_class_path, java_home);
274 strcat(boot_class_path, "/lib/resources.jar:");
275 strcat(boot_class_path, java_home);
276 strcat(boot_class_path, "/lib/rt.jar:");
277 strcat(boot_class_path, java_home);
278 strcat(boot_class_path, "/lib/sunrsasign.jar:");
279 strcat(boot_class_path, java_home);
280 strcat(boot_class_path, "/lib/jsse.jar:");
281 strcat(boot_class_path, java_home);
282 strcat(boot_class_path, "/lib/jce.jar:");
283 strcat(boot_class_path, java_home);
284 strcat(boot_class_path, "/lib/charsets.jar:");
285 strcat(boot_class_path, java_home);
286 strcat(boot_class_path, "/classes");
289 # error unknown classpath configuration
292 # if defined(WITH_CLASSPATH_GNU)
295 strlen(CACAO_VM_ZIP) +
297 strlen(CLASSPATH_CLASSES) +
300 boot_class_path = MNEW(char, len);
302 strcpy(boot_class_path, CACAO_VM_ZIP);
303 strcat(boot_class_path, ":");
304 strcat(boot_class_path, CLASSPATH_CLASSES);
306 # elif defined(WITH_CLASSPATH_SUN)
308 /* This is the bootclasspath taken from HotSpot (see
309 hotspot/src/share/vm/runtime/os.cpp
310 (os::set_boot_path)). */
313 strlen(CLASSPATH_PREFIX"/lib/resources.jar:") +
314 strlen(CLASSPATH_PREFIX"/lib/rt.jar:") +
315 strlen(CLASSPATH_PREFIX"/lib/sunrsasign.jar:") +
316 strlen(CLASSPATH_PREFIX"/lib/jsse.jar:") +
317 strlen(CLASSPATH_PREFIX"/lib/jce.jar:") +
318 strlen(CLASSPATH_PREFIX"/lib/charsets.jar:") +
319 strlen(CLASSPATH_PREFIX"/classes") +
322 boot_class_path = MNEW(char, len);
324 strcpy(boot_class_path, CLASSPATH_PREFIX"/lib/resources.jar:");
325 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/rt.jar:");
326 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/sunrsasign.jar:");
327 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/jsse.jar:");
328 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/jce.jar:");
329 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/charsets.jar:");
330 strcat(boot_class_path, CLASSPATH_PREFIX"/classes");
332 # elif defined(WITH_CLASSPATH_CLDC1_1)
335 strlen(CLASSPATH_CLASSES) +
338 boot_class_path = MNEW(char, len);
340 strcpy(boot_class_path, CLASSPATH_CLASSES);
343 # error unknown classpath configuration
348 properties_add("sun.boot.class.path", boot_class_path);
349 properties_add("java.boot.class.path", boot_class_path);
351 #if defined(ENABLE_JAVASE)
353 /* Set the classpath. */
355 p = getenv("CLASSPATH");
358 class_path = MNEW(char, strlen(p) + strlen("0"));
359 strcpy(class_path, p);
362 class_path = MNEW(char, strlen(".") + strlen("0"));
363 strcpy(class_path, ".");
366 properties_add("java.class.path", class_path);
368 /* Add java.vm properties. */
370 properties_add("java.vm.specification.version", "1.0");
371 properties_add("java.vm.specification.vendor", "Sun Microsystems Inc.");
372 properties_add("java.vm.specification.name", "Java Virtual Machine Specification");
373 properties_add("java.vm.version", VERSION);
374 properties_add("java.vm.vendor", "CACAO Team");
375 properties_add("java.vm.name", "CACAO");
377 # if defined(ENABLE_INTRP)
379 /* XXX We don't support java.lang.Compiler */
380 /* properties_add("java.compiler", "cacao.intrp"); */
381 properties_add("java.vm.info", "interpreted mode");
386 /* XXX We don't support java.lang.Compiler */
387 /* properties_add("java.compiler", "cacao.jit"); */
388 properties_add("java.vm.info", "JIT mode");
391 # if defined(WITH_CLASSPATH_GNU)
393 /* Get properties from system. */
397 env_user = getenv("USER");
398 env_home = getenv("HOME");
399 env_lang = getenv("LANG");
401 utsnamebuf = NEW(struct utsname);
405 properties_add("java.runtime.version", VERSION);
406 properties_add("java.runtime.name", "CACAO");
408 properties_add("java.specification.version", "1.5");
409 properties_add("java.specification.vendor", "Sun Microsystems Inc.");
410 properties_add("java.specification.name", "Java Platform API Specification");
412 properties_add("java.version", JAVA_VERSION);
413 properties_add("java.vendor", "GNU Classpath");
414 properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/");
416 properties_add("java.class.version", CLASS_VERSION);
418 properties_add("gnu.classpath.boot.library.path", boot_library_path);
420 /* Get and set java.library.path. */
422 java_library_path = getenv("LD_LIBRARY_PATH");
424 if (java_library_path == NULL)
425 java_library_path = "";
427 properties_add("java.library.path", java_library_path);
429 properties_add("java.io.tmpdir", "/tmp");
431 # if defined(ENABLE_INTRP)
433 properties_add("gnu.java.compiler.name", "cacao.intrp");
438 properties_add("gnu.java.compiler.name", "cacao.jit");
441 /* set the java.ext.dirs property */
443 len = strlen(java_home) + strlen("/jre/lib/ext") + strlen("0");
445 extdirs = MNEW(char, len);
447 strcpy(extdirs, java_home);
448 strcat(extdirs, "/jre/lib/ext");
450 properties_add("java.ext.dirs", extdirs);
452 properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed");
454 # if defined(DISABLE_GC)
455 /* When we disable the GC, we mmap the whole heap to a specific
456 address, so we can compare call traces. For this reason we have
457 to add the same properties on different machines, otherwise
458 more memory may be allocated (e.g. strlen("i386")
459 vs. strlen("alpha"). */
461 properties_add("os.arch", "unknown");
462 properties_add("os.name", "unknown");
463 properties_add("os.version", "unknown");
465 properties_add("os.arch", JAVA_ARCH);
466 properties_add("os.name", utsnamebuf->sysname);
467 properties_add("os.version", utsnamebuf->release);
470 # if WORDS_BIGENDIAN == 1
471 properties_add("gnu.cpu.endian", "big");
473 properties_add("gnu.cpu.endian", "little");
476 properties_add("file.separator", "/");
477 properties_add("path.separator", ":");
478 properties_add("line.separator", "\n");
480 properties_add("user.name", env_user ? env_user : "null");
481 properties_add("user.home", env_home ? env_home : "null");
482 properties_add("user.dir", cwd ? cwd : "null");
486 if (env_lang != NULL) {
487 /* get the local stuff from the environment */
489 if (strlen(env_lang) <= 2) {
490 properties_add("user.language", env_lang);
493 if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
494 lang = MNEW(char, 3);
495 strncpy(lang, (char *) &env_lang[0], 2);
498 country = MNEW(char, 3);
499 strncpy(country, (char *) &env_lang[3], 2);
502 properties_add("user.language", lang);
503 properties_add("user.country", country);
508 /* if no default locale was specified, use `en_US' */
510 properties_add("user.language", "en");
511 properties_add("user.country", "US");
514 # elif defined(WITH_CLASSPATH_SUN)
516 /* Actually this property is set by OpenJDK, but we need it in
517 nativevm_preinit(). */
519 properties_add("sun.boot.library.path", boot_library_path);
523 # error unknown classpath configuration
527 #elif defined(ENABLE_JAVAME_CLDC1_1)
529 properties_add("microedition.configuration", "CLDC-1.1");
530 properties_add("microedition.platform", "generic");
531 properties_add("microedition.encoding", "ISO8859_1");
532 properties_add("microedition.profiles", "");
536 # error unknown Java configuration
542 /* properties_add **************************************************************
544 Adds a property entry to the internal property list. If there's
545 already an entry with the same key, replace it.
547 *******************************************************************************/
549 void properties_add(char *key, char *value)
551 list_properties_entry_t *pe;
553 /* search for the entry */
555 for (pe = list_first_unsynced(list_properties); pe != NULL;
556 pe = list_next_unsynced(list_properties, pe)) {
557 if (strcmp(pe->key, key) == 0) {
558 /* entry was found, replace the value */
561 if (opt_DebugProperties) {
562 printf("[properties_add: key=%s, old value=%s, new value=%s]\n",
563 key, pe->value, value);
573 /* entry was not found, insert a new one */
576 if (opt_DebugProperties) {
577 printf("[properties_add: key=%s, value=%s]\n", key, value);
581 pe = NEW(list_properties_entry_t);
586 list_add_last_unsynced(list_properties, pe);
590 /* properties_get **************************************************************
592 Get a property entry from the internal property list.
594 *******************************************************************************/
596 char *properties_get(char *key)
598 list_properties_entry_t *pe;
600 for (pe = list_first_unsynced(list_properties); pe != NULL;
601 pe = list_next_unsynced(list_properties, pe)) {
602 if (strcmp(pe->key, key) == 0)
610 /* properties_system_add *******************************************************
612 Adds a given property to the Java system properties.
614 *******************************************************************************/
616 void properties_system_add(java_handle_t *p, char *key, char *value)
623 /* search for method to add properties */
625 LLNI_class_get(p, c);
627 m = class_resolveclassmethod(c,
629 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
636 /* add to the Java system properties */
638 k = javastring_new_from_utf_string(key);
639 v = javastring_new_from_utf_string(value);
641 (void) vm_call_method(m, p, k, v);
645 /* properties_system_add_all ***************************************************
647 Adds all properties from the properties list to the Java system
651 p.... is actually a java_util_Properties structure
653 *******************************************************************************/
655 #if defined(ENABLE_JAVASE)
656 void properties_system_add_all(java_handle_t *p)
658 list_properties_entry_t *pe;
662 java_handle_t *value;
664 /* search for method to add properties */
666 LLNI_class_get(p, c);
668 m = class_resolveclassmethod(c,
670 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
677 /* process all properties stored in the internal table */
679 for (pe = list_first(list_properties); pe != NULL;
680 pe = list_next(list_properties, pe)) {
681 /* add to the Java system properties */
683 key = javastring_new_from_utf_string(pe->key);
684 value = javastring_new_from_utf_string(pe->value);
686 (void) vm_call_method(m, (java_handle_t *) p, key, value);
689 #endif /* defined(ENABLE_JAVASE) */
692 /* properties_dump *************************************************************
694 Dump all property entries.
696 *******************************************************************************/
698 void properties_dump(void)
701 list_properties_entry_t *pe;
705 for (pe = list_first_unsynced(l); pe != NULL;
706 pe = list_next_unsynced(l, pe)) {
707 log_println("[properties_dump: key=%s, value=%s]", pe->key, pe->value);
713 * These are local overrides for various environment variables in Emacs.
714 * Please do not remove this and leave it at the end of the file, where
715 * Emacs will automagically detect them.
716 * ---------------------------------------------------------------------
719 * indent-tabs-mode: t