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/llni.h"
40 #include "toolbox/list.h"
41 #include "toolbox/util.h"
44 #include "vm/global.h"
45 #include "vm/method.h"
46 #include "vm/options.h"
48 #include "vm/properties.h"
49 #include "vm/string.hpp"
52 #include "vm/jit/asmpart.h"
55 /* internal property structure ************************************************/
57 typedef struct list_properties_entry_t list_properties_entry_t;
59 struct list_properties_entry_t {
66 /* global variables ***********************************************************/
68 static list_t *list_properties = NULL;
71 /* properties_init *************************************************************
73 Initialize the properties list and fill the list with default
76 *******************************************************************************/
78 void properties_init(void)
80 TRACESUBSYSTEMINITIALIZATION("properties_init");
82 list_properties = list_create(OFFSET(list_properties_entry_t, linkage));
86 /* properties_set **************************************************************
88 Fill the properties list with default values.
90 *******************************************************************************/
92 void properties_set(void)
98 char *boot_class_path;
100 #if defined(ENABLE_JAVASE)
102 char *boot_library_path;
106 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
113 struct utsname *utsnamebuf;
115 char *java_library_path;
119 #if defined(ENABLE_JRE_LAYOUT)
120 /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
122 p = MNEW(char, 4096);
124 if (readlink("/proc/self/exe", p, 4095) == -1)
125 vm_abort("properties_set: readlink failed: %s\n", strerror(errno));
127 /* We have a path like:
129 /path/to/executable/bin/java
133 /path/to/executeable/jre/bin/java
135 Now let's strip two levels. */
140 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
144 java_home = strdup(p);
146 /* Set the path to Java core native libraries. */
148 len = strlen(java_home) + strlen("/lib/classpath") + strlen("0");
150 boot_library_path = MNEW(char, len);
152 strcpy(boot_library_path, java_home);
153 strcat(boot_library_path, "/lib/classpath");
155 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
157 /* Find correct java.home. We check if there is a JRE
160 /* NOTE: We use the server VM here as it should be available on
161 all architectures. */
165 strlen("/jre/lib/"JAVA_ARCH"/server/libjvm.so") +
168 java_home = MNEW(char, len);
170 strcpy(java_home, p);
171 strcat(java_home, "/jre/lib/"JAVA_ARCH"/server/libjvm.so");
173 /* Check if that libjvm.so exists. */
175 if (os_access(java_home, F_OK) == 0) {
176 /* Yes, we add /jre to java.home. */
178 strcpy(java_home, p);
179 strcat(java_home, "/jre");
182 /* No, java.home is parent directory. */
184 strcpy(java_home, p);
187 /* Set the path to Java core native libraries. */
189 len = strlen(java_home) + strlen("/lib/"JAVA_ARCH) + strlen("0");
191 boot_library_path = MNEW(char, len);
193 strcpy(boot_library_path, java_home);
194 strcat(boot_library_path, "/lib/"JAVA_ARCH);
197 # error unknown classpath configuration
205 java_home = CACAO_PREFIX;
207 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
209 boot_library_path = JAVA_RUNTIME_LIBRARY_LIBDIR"/classpath";
211 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
213 boot_library_path = JAVA_RUNTIME_LIBRARY_LIBDIR;
215 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
217 /* No boot_library_path required. */
220 # error unknown classpath configuration
224 properties_add("java.home", java_home);
226 /* Set the bootclasspath. */
228 p = getenv("BOOTCLASSPATH");
231 boot_class_path = MNEW(char, strlen(p) + strlen("0"));
232 strcpy(boot_class_path, p);
235 #if defined(ENABLE_JRE_LAYOUT)
236 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
239 strlen(java_home) + strlen("/share/cacao/vm.zip:") +
240 strlen(java_home) + strlen("/share/classpath/glibj.zip") +
243 boot_class_path = MNEW(char, len);
245 strcpy(boot_class_path, java_home);
246 strcat(boot_class_path, "/share/cacao/vm.zip");
247 strcat(boot_class_path, ":");
248 strcat(boot_class_path, java_home);
249 strcat(boot_class_path, "/share/classpath/glibj.zip");
251 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
253 /* This is the bootclasspath taken from HotSpot (see
254 hotspot/src/share/vm/runtime/os.cpp
255 (os::set_boot_path)). */
258 strlen(java_home) + strlen("/lib/resources.jar:") +
259 strlen(java_home) + strlen("/lib/rt.jar:") +
260 strlen(java_home) + strlen("/lib/sunrsasign.jar:") +
261 strlen(java_home) + strlen("/lib/jsse.jar:") +
262 strlen(java_home) + strlen("/lib/jce.jar:") +
263 strlen(java_home) + strlen("/lib/charsets.jar:") +
264 strlen(java_home) + strlen("/classes") +
267 boot_class_path = MNEW(char, len);
269 strcpy(boot_class_path, java_home);
270 strcat(boot_class_path, "/lib/resources.jar:");
271 strcat(boot_class_path, java_home);
272 strcat(boot_class_path, "/lib/rt.jar:");
273 strcat(boot_class_path, java_home);
274 strcat(boot_class_path, "/lib/sunrsasign.jar:");
275 strcat(boot_class_path, java_home);
276 strcat(boot_class_path, "/lib/jsse.jar:");
277 strcat(boot_class_path, java_home);
278 strcat(boot_class_path, "/lib/jce.jar:");
279 strcat(boot_class_path, java_home);
280 strcat(boot_class_path, "/lib/charsets.jar:");
281 strcat(boot_class_path, java_home);
282 strcat(boot_class_path, "/classes");
285 # error unknown classpath configuration
288 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
291 strlen(CACAO_VM_ZIP) +
293 strlen(JAVA_RUNTIME_LIBRARY_CLASSES) +
296 boot_class_path = MNEW(char, len);
298 strcpy(boot_class_path, CACAO_VM_ZIP);
299 strcat(boot_class_path, ":");
300 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_CLASSES);
302 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
304 /* This is the bootclasspath taken from HotSpot (see
305 hotspot/src/share/vm/runtime/os.cpp
306 (os::set_boot_path)). */
309 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/resources.jar:") +
310 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/rt.jar:") +
311 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/sunrsasign.jar:") +
312 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jsse.jar:") +
313 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jce.jar:") +
314 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/lib/charsets.jar:") +
315 strlen(JAVA_RUNTIME_LIBRARY_PREFIX"/classes") +
318 boot_class_path = MNEW(char, len);
320 strcpy(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/resources.jar:");
321 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/rt.jar:");
322 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/sunrsasign.jar:");
323 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jsse.jar:");
324 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/jce.jar:");
325 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/lib/charsets.jar:");
326 strcat(boot_class_path, JAVA_RUNTIME_LIBRARY_PREFIX"/classes");
328 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_CLDC1_1)
331 strlen(JAVA_RUNTIME_LIBRARY_CLASSES) +
334 boot_class_path = MNEW(char, len);
336 strcpy(boot_class_path, JAVA_RUNTIME_LIBRARY_CLASSES);
339 # error unknown classpath configuration
344 properties_add("sun.boot.class.path", boot_class_path);
345 properties_add("java.boot.class.path", boot_class_path);
347 #if defined(ENABLE_JAVASE)
349 /* Set the classpath. */
351 p = getenv("CLASSPATH");
354 class_path = MNEW(char, strlen(p) + strlen("0"));
355 strcpy(class_path, p);
358 class_path = MNEW(char, strlen(".") + strlen("0"));
359 strcpy(class_path, ".");
362 properties_add("java.class.path", class_path);
364 /* Add java.vm properties. */
366 properties_add("java.vm.specification.version", "1.0");
367 properties_add("java.vm.specification.vendor", "Sun Microsystems Inc.");
368 properties_add("java.vm.specification.name", "Java Virtual Machine Specification");
369 properties_add("java.vm.version", VERSION);
370 properties_add("java.vm.vendor", "CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO");
371 properties_add("java.vm.name", "CACAO");
373 # if defined(ENABLE_INTRP)
375 /* XXX We don't support java.lang.Compiler */
376 /* properties_add("java.compiler", "cacao.intrp"); */
377 properties_add("java.vm.info", "interpreted mode");
382 /* XXX We don't support java.lang.Compiler */
383 /* properties_add("java.compiler", "cacao.jit"); */
384 properties_add("java.vm.info", "JIT mode");
387 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
389 /* Get properties from system. */
393 env_user = getenv("USER");
394 env_home = getenv("HOME");
395 env_lang = getenv("LANG");
397 utsnamebuf = NEW(struct utsname);
401 properties_add("java.runtime.version", VERSION);
402 properties_add("java.runtime.name", "CACAO");
404 properties_add("java.specification.version", "1.5");
405 properties_add("java.specification.vendor", "Sun Microsystems Inc.");
406 properties_add("java.specification.name", "Java Platform API Specification");
408 properties_add("java.version", JAVA_VERSION);
409 properties_add("java.vendor", "GNU Classpath");
410 properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/");
412 properties_add("java.class.version", CLASS_VERSION);
414 properties_add("gnu.classpath.boot.library.path", boot_library_path);
416 /* Get and set java.library.path. */
418 java_library_path = getenv("LD_LIBRARY_PATH");
420 if (java_library_path == NULL)
421 java_library_path = "";
423 properties_add("java.library.path", java_library_path);
425 properties_add("java.io.tmpdir", "/tmp");
427 # if defined(ENABLE_INTRP)
429 properties_add("gnu.java.compiler.name", "cacao.intrp");
434 properties_add("gnu.java.compiler.name", "cacao.jit");
437 /* Set the java.ext.dirs property. */
439 len = strlen(java_home) + strlen("/jre/lib/ext") + strlen("0");
441 extdirs = MNEW(char, len);
443 sprintf(extdirs, "%s/jre/lib/ext", java_home);
445 properties_add("java.ext.dirs", extdirs);
447 /* Set the java.ext.endorsed property. */
449 len = strlen(java_home) + strlen("/jre/lib/endorsed") + strlen("0");
451 endorseddirs = MNEW(char, len);
453 sprintf(endorseddirs, "%s/jre/lib/endorsed", java_home);
455 properties_add("java.endorsed.dirs", endorseddirs);
457 # if defined(DISABLE_GC)
458 /* When we disable the GC, we mmap the whole heap to a specific
459 address, so we can compare call traces. For this reason we have
460 to add the same properties on different machines, otherwise
461 more memory may be allocated (e.g. strlen("i386")
462 vs. strlen("alpha"). */
464 properties_add("os.arch", "unknown");
465 properties_add("os.name", "unknown");
466 properties_add("os.version", "unknown");
468 properties_add("os.arch", JAVA_ARCH);
469 properties_add("os.name", utsnamebuf->sysname);
470 properties_add("os.version", utsnamebuf->release);
473 # if WORDS_BIGENDIAN == 1
474 properties_add("gnu.cpu.endian", "big");
476 properties_add("gnu.cpu.endian", "little");
479 properties_add("file.separator", "/");
480 properties_add("path.separator", ":");
481 properties_add("line.separator", "\n");
483 properties_add("user.name", env_user ? env_user : "null");
484 properties_add("user.home", env_home ? env_home : "null");
485 properties_add("user.dir", cwd ? cwd : "null");
489 if (env_lang != NULL) {
490 /* get the local stuff from the environment */
492 if (strlen(env_lang) <= 2) {
493 properties_add("user.language", env_lang);
496 if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
497 lang = MNEW(char, 3);
498 strncpy(lang, (char *) &env_lang[0], 2);
501 country = MNEW(char, 3);
502 strncpy(country, (char *) &env_lang[3], 2);
505 properties_add("user.language", lang);
506 properties_add("user.country", country);
511 /* if no default locale was specified, use `en_US' */
513 properties_add("user.language", "en");
514 properties_add("user.country", "US");
517 # elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
519 /* Actually this property is set by OpenJDK, but we need it in
520 nativevm_preinit(). */
522 properties_add("sun.boot.library.path", boot_library_path);
524 /* Set the java.ext.dirs property. */
527 strlen(java_home) + strlen("/lib/ext") +
529 strlen("/usr/java/packages/lib/ext") +
532 extdirs = MNEW(char, len);
534 sprintf(extdirs, "%s/lib/ext:/usr/java/packages/lib/ext", java_home);
536 properties_add("java.ext.dirs", extdirs);
538 /* Set the java.ext.endorsed property. */
540 len = strlen(java_home) + strlen("/lib/endorsed") + strlen("0");
542 endorseddirs = MNEW(char, len);
544 sprintf(endorseddirs, "%s/lib/endorsed", java_home);
546 properties_add("java.endorsed.dirs", endorseddirs);
550 # error unknown classpath configuration
554 #elif defined(ENABLE_JAVAME_CLDC1_1)
556 properties_add("microedition.configuration", "CLDC-1.1");
557 properties_add("microedition.platform", "generic");
558 properties_add("microedition.encoding", "ISO8859_1");
559 properties_add("microedition.profiles", "");
563 # error unknown Java configuration
569 /* properties_add **************************************************************
571 Adds a property entry to the internal property list. If there's
572 already an entry with the same key, replace it.
574 *******************************************************************************/
576 void properties_add(const char *key, const char *value)
578 list_properties_entry_t *pe;
580 /* search for the entry */
582 for (pe = list_first(list_properties); pe != NULL;
583 pe = list_next(list_properties, pe)) {
584 if (strcmp(pe->key, key) == 0) {
585 /* entry was found, replace the value */
588 if (opt_DebugProperties) {
589 printf("[properties_add: key=%s, old value=%s, new value=%s]\n",
590 key, pe->value, value);
600 /* entry was not found, insert a new one */
603 if (opt_DebugProperties) {
604 printf("[properties_add: key=%s, value=%s]\n", key, value);
608 pe = NEW(list_properties_entry_t);
613 list_add_last(list_properties, pe);
617 /* properties_get **************************************************************
619 Get a property entry from the internal property list.
621 *******************************************************************************/
623 const char *properties_get(const char *key)
625 list_properties_entry_t *pe;
627 for (pe = list_first(list_properties); pe != NULL;
628 pe = list_next(list_properties, pe)) {
629 if (strcmp(pe->key, key) == 0)
637 /* properties_system_add *******************************************************
639 Adds a given property to the Java system properties.
641 *******************************************************************************/
643 void properties_system_add(java_handle_t *p, const char *key, const char *value)
650 /* search for method to add properties */
652 LLNI_class_get(p, c);
654 m = class_resolveclassmethod(c,
656 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
663 /* add to the Java system properties */
665 k = javastring_new_from_utf_string(key);
666 v = javastring_new_from_utf_string(value);
668 (void) vm_call_method(m, p, k, v);
672 /* properties_system_add_all ***************************************************
674 Adds all properties from the properties list to the Java system
678 p.... is actually a java_util_Properties structure
680 *******************************************************************************/
682 #if defined(ENABLE_JAVASE)
683 void properties_system_add_all(java_handle_t *p)
685 list_properties_entry_t *pe;
689 java_handle_t *value;
691 /* search for method to add properties */
693 LLNI_class_get(p, c);
695 m = class_resolveclassmethod(c,
697 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
704 /* process all properties stored in the internal table */
706 for (pe = list_first(list_properties); pe != NULL;
707 pe = list_next(list_properties, pe)) {
708 /* add to the Java system properties */
710 key = javastring_new_from_utf_string(pe->key);
711 value = javastring_new_from_utf_string(pe->value);
713 (void) vm_call_method(m, (java_handle_t *) p, key, value);
716 #endif /* defined(ENABLE_JAVASE) */
719 /* properties_dump *************************************************************
721 Dump all property entries.
723 *******************************************************************************/
725 void properties_dump(void)
728 list_properties_entry_t *pe;
730 /* For convenience. */
734 for (pe = list_first(l); pe != NULL; pe = list_next(l, pe)) {
735 log_println("[properties_dump: key=%s, value=%s]", pe->key, pe->value);
741 * These are local overrides for various environment variables in Emacs.
742 * Please do not remove this and leave it at the end of the file, where
743 * Emacs will automagically detect them.
744 * ---------------------------------------------------------------------
747 * indent-tabs-mode: t