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
34 #include <sys/utsname.h>
36 #include "mm/memory.h"
38 #include "native/jni.h"
39 #include "native/llni.h"
41 #include "toolbox/list.h"
42 #include "toolbox/util.h"
44 #include "vm/global.h"
45 #include "vm/properties.h"
46 #include "vm/string.hpp"
49 #include "vm/jit/asmpart.h"
51 #include "vmcore/class.h"
52 #include "vmcore/method.h"
53 #include "vmcore/options.h"
54 #include "vmcore/os.hpp"
57 /* internal property structure ************************************************/
59 typedef struct list_properties_entry_t list_properties_entry_t;
61 struct list_properties_entry_t {
68 /* global variables ***********************************************************/
70 static list_t *list_properties = NULL;
73 /* properties_init *************************************************************
75 Initialize the properties list and fill the list with default
78 *******************************************************************************/
80 void properties_init(void)
82 TRACESUBSYSTEMINITIALIZATION("properties_init");
84 list_properties = list_create(OFFSET(list_properties_entry_t, linkage));
88 /* properties_set **************************************************************
90 Fill the properties list with default values.
92 *******************************************************************************/
94 void properties_set(void)
100 char *boot_class_path;
102 #if defined(ENABLE_JAVASE)
104 char *boot_library_path;
108 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
115 struct utsname *utsnamebuf;
117 char *java_library_path;
121 #if defined(ENABLE_JRE_LAYOUT)
122 /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
124 p = MNEW(char, 4096);
126 if (readlink("/proc/self/exe", p, 4095) == -1)
127 vm_abort("properties_set: readlink failed: %s\n", strerror(errno));
129 /* We have a path like:
131 /path/to/executable/bin/java
135 /path/to/executeable/jre/bin/java
137 Now let's strip two levels. */
142 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
146 java_home = strdup(p);
148 /* Set the path to Java core native libraries. */
150 len = strlen(java_home) + strlen("/lib/classpath") + strlen("0");
152 boot_library_path = MNEW(char, len);
154 strcpy(boot_library_path, java_home);
155 strcat(boot_library_path, "/lib/classpath");
157 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
159 /* Find correct java.home. We check if there is a JRE
162 /* NOTE: We use the server VM here as it should be available on
163 all architectures. */
167 strlen("/jre/lib/"JAVA_ARCH"/server/libjvm.so") +
170 java_home = MNEW(char, len);
172 strcpy(java_home, p);
173 strcat(java_home, "/jre/lib/"JAVA_ARCH"/server/libjvm.so");
175 /* Check if that libjvm.so exists. */
177 if (os_access(java_home, F_OK) == 0) {
178 /* Yes, we add /jre to java.home. */
180 strcpy(java_home, p);
181 strcat(java_home, "/jre");
184 /* No, java.home is parent directory. */
186 strcpy(java_home, p);
189 /* Set the path to Java core native libraries. */
191 len = strlen(java_home) + strlen("/lib/"JAVA_ARCH) + strlen("0");
193 boot_library_path = MNEW(char, len);
195 strcpy(boot_library_path, java_home);
196 strcat(boot_library_path, "/lib/"JAVA_ARCH);
199 # error unknown classpath configuration
207 java_home = CACAO_PREFIX;
209 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
211 boot_library_path = JAVA_RUNTIME_LIBRARY_LIBDIR"/classpath";
213 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
215 boot_library_path = JAVA_RUNTIME_LIBRARY_LIBDIR;
217 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
219 /* No boot_library_path required. */
222 # error unknown classpath configuration
226 properties_add("java.home", java_home);
228 /* Set the bootclasspath. */
230 p = getenv("BOOTCLASSPATH");
233 boot_class_path = MNEW(char, strlen(p) + strlen("0"));
234 strcpy(boot_class_path, p);
237 #if defined(ENABLE_JRE_LAYOUT)
238 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
241 strlen(java_home) + strlen("/share/cacao/vm.zip:") +
242 strlen(java_home) + strlen("/share/classpath/glibj.zip") +
245 boot_class_path = MNEW(char, len);
247 strcpy(boot_class_path, java_home);
248 strcat(boot_class_path, "/share/cacao/vm.zip");
249 strcat(boot_class_path, ":");
250 strcat(boot_class_path, java_home);
251 strcat(boot_class_path, "/share/classpath/glibj.zip");
253 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
255 /* This is the bootclasspath taken from HotSpot (see
256 hotspot/src/share/vm/runtime/os.cpp
257 (os::set_boot_path)). */
260 strlen(java_home) + strlen("/lib/resources.jar:") +
261 strlen(java_home) + strlen("/lib/rt.jar:") +
262 strlen(java_home) + strlen("/lib/sunrsasign.jar:") +
263 strlen(java_home) + strlen("/lib/jsse.jar:") +
264 strlen(java_home) + strlen("/lib/jce.jar:") +
265 strlen(java_home) + strlen("/lib/charsets.jar:") +
266 strlen(java_home) + strlen("/classes") +
269 boot_class_path = MNEW(char, len);
271 strcpy(boot_class_path, java_home);
272 strcat(boot_class_path, "/lib/resources.jar:");
273 strcat(boot_class_path, java_home);
274 strcat(boot_class_path, "/lib/rt.jar:");
275 strcat(boot_class_path, java_home);
276 strcat(boot_class_path, "/lib/sunrsasign.jar:");
277 strcat(boot_class_path, java_home);
278 strcat(boot_class_path, "/lib/jsse.jar:");
279 strcat(boot_class_path, java_home);
280 strcat(boot_class_path, "/lib/jce.jar:");
281 strcat(boot_class_path, java_home);
282 strcat(boot_class_path, "/lib/charsets.jar:");
283 strcat(boot_class_path, java_home);
284 strcat(boot_class_path, "/classes");
287 # error unknown classpath configuration
290 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
293 strlen(CACAO_VM_ZIP) +
295 strlen(JAVA_RUNTIME_LIBRARY_CLASSES) +
298 boot_class_path = MNEW(char, len);
300 strcpy(boot_class_path, CACAO_VM_ZIP);
301 strcat(boot_class_path, ":");
302 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_CLASSES);
304 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
306 /* This is the bootclasspath taken from HotSpot (see
307 hotspot/src/share/vm/runtime/os.cpp
308 (os::set_boot_path)). */
311 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/resources.jar:") +
312 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/rt.jar:") +
313 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/sunrsasign.jar:") +
314 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jsse.jar:") +
315 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jce.jar:") +
316 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/charsets.jar:") +
317 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/classes") +
320 boot_class_path = MNEW(char, len);
322 strcpy(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/resources.jar:");
323 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/rt.jar:");
324 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/sunrsasign.jar:");
325 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jsse.jar:");
326 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jce.jar:");
327 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/charsets.jar:");
328 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/classes");
330 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
333 strlen(JAVA_RUNTIME_LIBRARY_CLASSES) +
336 boot_class_path = MNEW(char, len);
338 strcpy(boot_class_path, JAVA_RUNTIME_LIBRARY_CLASSES);
341 # error unknown classpath configuration
346 properties_add("sun.boot.class.path", boot_class_path);
347 properties_add("java.boot.class.path", boot_class_path);
349 #if defined(ENABLE_JAVASE)
351 /* Set the classpath. */
353 p = getenv("CLASSPATH");
356 class_path = MNEW(char, strlen(p) + strlen("0"));
357 strcpy(class_path, p);
360 class_path = MNEW(char, strlen(".") + strlen("0"));
361 strcpy(class_path, ".");
364 properties_add("java.class.path", class_path);
366 /* Add java.vm properties. */
368 properties_add("java.vm.specification.version", "1.0");
369 properties_add("java.vm.specification.vendor", "Sun Microsystems Inc.");
370 properties_add("java.vm.specification.name", "Java Virtual Machine Specification");
371 properties_add("java.vm.version", VERSION);
372 properties_add("java.vm.vendor", "CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO");
373 properties_add("java.vm.name", "CACAO");
375 # if defined(ENABLE_INTRP)
377 /* XXX We don't support java.lang.Compiler */
378 /* properties_add("java.compiler", "cacao.intrp"); */
379 properties_add("java.vm.info", "interpreted mode");
384 /* XXX We don't support java.lang.Compiler */
385 /* properties_add("java.compiler", "cacao.jit"); */
386 properties_add("java.vm.info", "JIT mode");
389 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
391 /* Get properties from system. */
395 env_user = getenv("USER");
396 env_home = getenv("HOME");
397 env_lang = getenv("LANG");
399 utsnamebuf = NEW(struct utsname);
403 properties_add("java.runtime.version", VERSION);
404 properties_add("java.runtime.name", "CACAO");
406 properties_add("java.specification.version", "1.5");
407 properties_add("java.specification.vendor", "Sun Microsystems Inc.");
408 properties_add("java.specification.name", "Java Platform API Specification");
410 properties_add("java.version", JAVA_VERSION);
411 properties_add("java.vendor", "GNU Classpath");
412 properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/");
414 properties_add("java.class.version", CLASS_VERSION);
416 properties_add("gnu.classpath.boot.library.path", boot_library_path);
418 /* Get and set java.library.path. */
420 java_library_path = getenv("LD_LIBRARY_PATH");
422 if (java_library_path == NULL)
423 java_library_path = "";
425 properties_add("java.library.path", java_library_path);
427 properties_add("java.io.tmpdir", "/tmp");
429 # if defined(ENABLE_INTRP)
431 properties_add("gnu.java.compiler.name", "cacao.intrp");
436 properties_add("gnu.java.compiler.name", "cacao.jit");
439 /* Set the java.ext.dirs property. */
441 len = strlen(java_home) + strlen("/jre/lib/ext") + strlen("0");
443 extdirs = MNEW(char, len);
445 sprintf(extdirs, "%s/jre/lib/ext", java_home);
447 properties_add("java.ext.dirs", extdirs);
449 /* Set the java.ext.endorsed property. */
451 len = strlen(java_home) + strlen("/jre/lib/endorsed") + strlen("0");
453 endorseddirs = MNEW(char, len);
455 sprintf(endorseddirs, "%s/jre/lib/endorsed", java_home);
457 properties_add("java.endorsed.dirs", endorseddirs);
459 # if defined(DISABLE_GC)
460 /* When we disable the GC, we mmap the whole heap to a specific
461 address, so we can compare call traces. For this reason we have
462 to add the same properties on different machines, otherwise
463 more memory may be allocated (e.g. strlen("i386")
464 vs. strlen("alpha"). */
466 properties_add("os.arch", "unknown");
467 properties_add("os.name", "unknown");
468 properties_add("os.version", "unknown");
470 properties_add("os.arch", JAVA_ARCH);
471 properties_add("os.name", utsnamebuf->sysname);
472 properties_add("os.version", utsnamebuf->release);
475 # if WORDS_BIGENDIAN == 1
476 properties_add("gnu.cpu.endian", "big");
478 properties_add("gnu.cpu.endian", "little");
481 properties_add("file.separator", "/");
482 properties_add("path.separator", ":");
483 properties_add("line.separator", "\n");
485 properties_add("user.name", env_user ? env_user : "null");
486 properties_add("user.home", env_home ? env_home : "null");
487 properties_add("user.dir", cwd ? cwd : "null");
491 if (env_lang != NULL) {
492 /* get the local stuff from the environment */
494 if (strlen(env_lang) <= 2) {
495 properties_add("user.language", env_lang);
498 if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
499 lang = MNEW(char, 3);
500 strncpy(lang, (char *) &env_lang[0], 2);
503 country = MNEW(char, 3);
504 strncpy(country, (char *) &env_lang[3], 2);
507 properties_add("user.language", lang);
508 properties_add("user.country", country);
513 /* if no default locale was specified, use `en_US' */
515 properties_add("user.language", "en");
516 properties_add("user.country", "US");
519 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
521 /* Actually this property is set by OpenJDK, but we need it in
522 nativevm_preinit(). */
524 properties_add("sun.boot.library.path", boot_library_path);
526 /* Set the java.ext.dirs property. */
529 strlen(java_home) + strlen("/lib/ext") +
531 strlen("/usr/java/packages/lib/ext") +
534 extdirs = MNEW(char, len);
536 sprintf(extdirs, "%s/lib/ext:/usr/java/packages/lib/ext", java_home);
538 properties_add("java.ext.dirs", extdirs);
540 /* Set the java.ext.endorsed property. */
542 len = strlen(java_home) + strlen("/lib/endorsed") + strlen("0");
544 endorseddirs = MNEW(char, len);
546 sprintf(endorseddirs, "%s/lib/endorsed", java_home);
548 properties_add("java.endorsed.dirs", endorseddirs);
552 # error unknown classpath configuration
556 #elif defined(ENABLE_JAVAME_CLDC1_1)
558 properties_add("microedition.configuration", "CLDC-1.1");
559 properties_add("microedition.platform", "generic");
560 properties_add("microedition.encoding", "ISO8859_1");
561 properties_add("microedition.profiles", "");
565 # error unknown Java configuration
571 /* properties_add **************************************************************
573 Adds a property entry to the internal property list. If there's
574 already an entry with the same key, replace it.
576 *******************************************************************************/
578 void properties_add(const char *key, const char *value)
580 list_properties_entry_t *pe;
582 /* search for the entry */
584 for (pe = list_first(list_properties); pe != NULL;
585 pe = list_next(list_properties, pe)) {
586 if (strcmp(pe->key, key) == 0) {
587 /* entry was found, replace the value */
590 if (opt_DebugProperties) {
591 printf("[properties_add: key=%s, old value=%s, new value=%s]\n",
592 key, pe->value, value);
602 /* entry was not found, insert a new one */
605 if (opt_DebugProperties) {
606 printf("[properties_add: key=%s, value=%s]\n", key, value);
610 pe = NEW(list_properties_entry_t);
615 list_add_last(list_properties, pe);
619 /* properties_get **************************************************************
621 Get a property entry from the internal property list.
623 *******************************************************************************/
625 const char *properties_get(const char *key)
627 list_properties_entry_t *pe;
629 for (pe = list_first(list_properties); pe != NULL;
630 pe = list_next(list_properties, pe)) {
631 if (strcmp(pe->key, key) == 0)
639 /* properties_system_add *******************************************************
641 Adds a given property to the Java system properties.
643 *******************************************************************************/
645 void properties_system_add(java_handle_t *p, const char *key, const char *value)
652 /* search for method to add properties */
654 LLNI_class_get(p, c);
656 m = class_resolveclassmethod(c,
658 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
665 /* add to the Java system properties */
667 k = javastring_new_from_utf_string(key);
668 v = javastring_new_from_utf_string(value);
670 (void) vm_call_method(m, p, k, v);
674 /* properties_system_add_all ***************************************************
676 Adds all properties from the properties list to the Java system
680 p.... is actually a java_util_Properties structure
682 *******************************************************************************/
684 #if defined(ENABLE_JAVASE)
685 void properties_system_add_all(java_handle_t *p)
687 list_properties_entry_t *pe;
691 java_handle_t *value;
693 /* search for method to add properties */
695 LLNI_class_get(p, c);
697 m = class_resolveclassmethod(c,
699 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
706 /* process all properties stored in the internal table */
708 for (pe = list_first(list_properties); pe != NULL;
709 pe = list_next(list_properties, pe)) {
710 /* add to the Java system properties */
712 key = javastring_new_from_utf_string(pe->key);
713 value = javastring_new_from_utf_string(pe->value);
715 (void) vm_call_method(m, (java_handle_t *) p, key, value);
718 #endif /* defined(ENABLE_JAVASE) */
721 /* properties_dump *************************************************************
723 Dump all property entries.
725 *******************************************************************************/
727 void properties_dump(void)
730 list_properties_entry_t *pe;
732 /* For convenience. */
736 for (pe = list_first(l); pe != NULL; pe = list_next(l, pe)) {
737 log_println("[properties_dump: key=%s, value=%s]", pe->key, pe->value);
743 * These are local overrides for various environment variables in Emacs.
744 * Please do not remove this and leave it at the end of the file, where
745 * Emacs will automagically detect them.
746 * ---------------------------------------------------------------------
749 * indent-tabs-mode: t