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
25 $Id: properties.c 8401 2007-08-22 18:45:31Z twisti $
37 #include <sys/utsname.h>
39 #if defined(WITH_JRE_LAYOUT)
45 #include "mm/memory.h"
47 #include "native/jni.h"
49 #include "vm/global.h" /* required by java_lang_String.h */
50 #include "native/include/java_lang_String.h"
52 #include "toolbox/list.h"
53 #include "toolbox/util.h"
55 #include "vm/properties.h"
56 #include "vm/stringlocal.h"
59 #include "vm/jit/asmpart.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)
102 #if defined(ENABLE_JAVASE)
107 char *boot_library_path;
108 char *boot_class_path;
111 # if defined(WITH_CLASSPATH_GNU)
119 struct utsname *utsnamebuf;
121 char *java_library_path;
125 #if defined(WITH_JRE_LAYOUT)
126 /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
128 p = MNEW(char, 4096);
130 if (readlink("/proc/self/exe", p, 4095) == -1)
131 vm_abort("properties_set: readlink failed: %s\n", strerror(errno));
133 /* Get the path of the current executable. */
137 # if defined(WITH_CLASSPATH_GNU)
141 len = strlen(path) + strlen("/..") + strlen("0");
143 java_home = MNEW(char, len);
145 strcpy(java_home, p);
146 strcat(java_home, "/..");
148 /* Set the path to Java core native libraries. */
150 len = strlen(cacao_prefix) + 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_CLASSPATH_SUN)
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 (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);
187 strcat(java_home, "/..");
190 /* Set the path to Java core native libraries. */
192 len = strlen(java_home) + strlen("/lib/"JAVA_ARCH) + strlen("0");
194 boot_library_path = MNEW(char, len);
196 strcpy(boot_library_path, java_home);
197 strcat(boot_library_path, "/lib/"JAVA_ARCH);
200 # error unknown classpath configuration
208 java_home = CACAO_PREFIX;
210 # if defined(WITH_CLASSPATH_GNU)
211 boot_library_path = CLASSPATH_LIBDIR"/classpath";
213 boot_library_path = CLASSPATH_LIBDIR;
217 properties_add("java.home", java_home);
219 /* Set the bootclasspath. */
221 p = getenv("BOOTCLASSPATH");
224 boot_class_path = MNEW(char, strlen(p) + strlen("0"));
225 strcpy(boot_class_path, p);
228 #if defined(WITH_JRE_LAYOUT)
229 # if defined(WITH_CLASSPATH_GNU)
232 strlen(java_home) + strlen("/share/cacao/vm.zip:") +
233 strlen(java_home) + strlen("/share/classpath/glibj.zip") +
236 boot_class_path = MNEW(char, len);
238 strcpy(boot_class_path, java_home);
239 strcat(boot_class_path, "/share/cacao/vm.zip");
240 strcat(boot_class_path, ":");
241 strcat(boot_class_path, java_home);
242 strcat(boot_class_path, "/share/classpath/glibj.zip");
244 # elif defined(WITH_CLASSPATH_SUN)
246 /* This is the bootclasspath taken from HotSpot (see
247 hotspot/src/share/vm/runtime/os.cpp
248 (os::set_boot_path)). */
251 strlen(java_home) + strlen("/lib/resources.jar:") +
252 strlen(java_home) + strlen("/lib/rt.jar:") +
253 strlen(java_home) + strlen("/lib/sunrsasign.jar:") +
254 strlen(java_home) + strlen("/lib/jsse.jar:") +
255 strlen(java_home) + strlen("/lib/jce.jar:") +
256 strlen(java_home) + strlen("/lib/charsets.jar:") +
257 strlen(java_home) + strlen("/classes") +
260 boot_class_path = MNEW(char, len);
262 strcpy(boot_class_path, java_home);
263 strcat(boot_class_path, "/lib/resources.jar:");
264 strcat(boot_class_path, java_home);
265 strcat(boot_class_path, "/lib/rt.jar:");
266 strcat(boot_class_path, java_home);
267 strcat(boot_class_path, "/lib/sunrsasign.jar:");
268 strcat(boot_class_path, java_home);
269 strcat(boot_class_path, "/lib/jsse.jar:");
270 strcat(boot_class_path, java_home);
271 strcat(boot_class_path, "/lib/jce.jar:");
272 strcat(boot_class_path, java_home);
273 strcat(boot_class_path, "/lib/charsets.jar:");
274 strcat(boot_class_path, java_home);
275 strcat(boot_class_path, "/classes");
278 # error unknown classpath configuration
281 # if defined(WITH_CLASSPATH_GNU)
284 strlen(CACAO_VM_ZIP) +
286 strlen(CLASSPATH_CLASSES) +
289 boot_class_path = MNEW(char, len);
291 strcpy(boot_class_path, CACAO_VM_ZIP);
292 strcat(boot_class_path, ":");
293 strcat(boot_class_path, CLASSPATH_CLASSES);
295 # elif defined(WITH_CLASSPATH_SUN)
297 /* This is the bootclasspath taken from HotSpot (see
298 hotspot/src/share/vm/runtime/os.cpp
299 (os::set_boot_path)). */
302 strlen(CLASSPATH_PREFIX"/lib/resources.jar:") +
303 strlen(CLASSPATH_PREFIX"/lib/rt.jar:") +
304 strlen(CLASSPATH_PREFIX"/lib/sunrsasign.jar:") +
305 strlen(CLASSPATH_PREFIX"/lib/jsse.jar:") +
306 strlen(CLASSPATH_PREFIX"/lib/jce.jar:") +
307 strlen(CLASSPATH_PREFIX"/lib/charsets.jar:") +
308 strlen(CLASSPATH_PREFIX"/classes") +
311 boot_class_path = MNEW(char, len);
313 strcpy(boot_class_path, CLASSPATH_PREFIX"/lib/resources.jar:");
314 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/rt.jar:");
315 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/sunrsasign.jar:");
316 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/jsse.jar:");
317 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/jce.jar:");
318 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/charsets.jar:");
319 strcat(boot_class_path, CLASSPATH_PREFIX"/classes");
321 # elif defined(WITH_CLASSPATH_CLDC1_1)
324 strlen(CLASSPATH_CLASSES) +
327 boot_class_path = MNEW(char, len);
329 strcat(boot_class_path, CLASSPATH_CLASSES);
332 # error unknown classpath configuration
337 properties_add("java.boot.class.path", boot_class_path);
338 properties_add("sun.boot.class.path", boot_class_path);
340 /* Set the classpath. */
342 p = getenv("CLASSPATH");
345 class_path = MNEW(char, strlen(p) + strlen("0"));
346 strcpy(class_path, p);
349 class_path = MNEW(char, strlen(".") + strlen("0"));
350 strcpy(class_path, ".");
353 properties_add("java.class.path", class_path);
355 #if defined(ENABLE_JAVASE)
357 /* get properties from system */
359 p = getenv("JAVA_HOME");
361 /* fill in system properties */
363 properties_add("java.vm.specification.version", "1.0");
364 properties_add("java.vm.specification.vendor", "Sun Microsystems Inc.");
365 properties_add("java.vm.specification.name", "Java Virtual Machine Specification");
366 properties_add("java.vm.version", VERSION);
367 properties_add("java.vm.vendor", "CACAO Team");
368 properties_add("java.vm.name", "CACAO");
370 # if defined(ENABLE_INTRP)
372 /* XXX We don't support java.lang.Compiler */
373 /* properties_add("java.compiler", "cacao.intrp"); */
374 properties_add("java.vm.info", "interpreted mode");
379 /* XXX We don't support java.lang.Compiler */
380 /* properties_add("java.compiler", "cacao.jit"); */
381 properties_add("java.vm.info", "JIT mode");
384 # if defined(WITH_CLASSPATH_GNU)
386 /* Get properties from system. */
390 env_user = getenv("USER");
391 env_home = getenv("HOME");
392 env_lang = getenv("LANG");
394 utsnamebuf = NEW(struct utsname);
398 properties_add("java.runtime.version", VERSION);
399 properties_add("java.runtime.name", "CACAO");
401 properties_add("java.specification.version", "1.5");
402 properties_add("java.specification.vendor", "Sun Microsystems Inc.");
403 properties_add("java.specification.name", "Java Platform API Specification");
405 properties_add("java.version", JAVA_VERSION);
406 properties_add("java.vendor", "GNU Classpath");
407 properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/");
409 properties_add("java.class.version", CLASS_VERSION);
411 # if defined(WITH_STATIC_CLASSPATH)
412 properties_add("gnu.classpath.boot.library.path", ".");
413 properties_add("java.library.path" , ".");
415 properties_add("gnu.classpath.boot.library.path", boot_library_path);
417 /* Get and set java.library.path. */
419 java_library_path = getenv("LD_LIBRARY_PATH");
421 if (java_library_path == NULL)
422 java_library_path = "";
424 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 strcpy(extdirs, java_home);
446 strcat(extdirs, "/jre/lib/ext");
448 properties_add("java.ext.dirs", extdirs);
450 properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed");
452 # if defined(DISABLE_GC)
453 /* When we disable the GC, we mmap the whole heap to a specific
454 address, so we can compare call traces. For this reason we have
455 to add the same properties on different machines, otherwise
456 more memory may be allocated (e.g. strlen("i386")
457 vs. strlen("alpha"). */
459 properties_add("os.arch", "unknown");
460 properties_add("os.name", "unknown");
461 properties_add("os.version", "unknown");
463 properties_add("os.arch", JAVA_ARCH);
464 properties_add("os.name", utsnamebuf->sysname);
465 properties_add("os.version", utsnamebuf->release);
468 # if defined(WITH_STATIC_CLASSPATH)
469 /* This is just for debugging purposes and can cause troubles in
472 properties_add("gnu.cpu.endian", "unknown");
474 # if WORDS_BIGENDIAN == 1
475 properties_add("gnu.cpu.endian", "big");
477 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_CLASSPATH_SUN)
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);
528 # error unknown classpath configuration
532 #elif defined(ENABLE_JAVAME_CLDC1_1)
534 properties_add("microedition.configuration", "CLDC-1.1");
535 properties_add("microedition.platform", "generic");
536 properties_add("microedition.encoding", "ISO8859_1");
537 properties_add("microedition.profiles", "");
541 # error unknown Java configuration
547 /* properties_add **************************************************************
549 Adds a property entry to the internal property list. If there's
550 already an entry with the same key, replace it.
552 *******************************************************************************/
554 void properties_add(char *key, char *value)
556 list_properties_entry_t *pe;
558 /* search for the entry */
560 for (pe = list_first_unsynced(list_properties); pe != NULL;
561 pe = list_next_unsynced(list_properties, pe)) {
562 if (strcmp(pe->key, key) == 0) {
563 /* entry was found, replace the value */
571 /* entry was not found, insert a new one */
573 pe = NEW(list_properties_entry_t);
578 list_add_last_unsynced(list_properties, pe);
582 /* properties_get **************************************************************
584 Get a property entry from the internal property list.
586 *******************************************************************************/
588 char *properties_get(char *key)
590 list_properties_entry_t *pe;
592 for (pe = list_first_unsynced(list_properties); pe != NULL;
593 pe = list_next_unsynced(list_properties, pe)) {
594 if (strcmp(pe->key, key) == 0)
602 /* properties_system_add *******************************************************
604 Adds a given property to the Java system properties.
606 *******************************************************************************/
608 void properties_system_add(java_handle_t *p, char *key, char *value)
614 /* search for method to add properties */
616 m = class_resolveclassmethod(p->vftbl->class,
618 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
625 /* add to the Java system properties */
627 k = javastring_new_from_utf_string(key);
628 v = javastring_new_from_utf_string(value);
630 (void) vm_call_method(m, p, k, v);
634 /* properties_system_add_all ***************************************************
636 Adds all properties from the properties list to the Java system
640 p.... is actually a java_util_Properties structure
642 *******************************************************************************/
644 #if defined(ENABLE_JAVASE)
645 void properties_system_add_all(java_handle_t *p)
647 list_properties_entry_t *pe;
650 java_handle_t *value;
652 /* search for method to add properties */
654 m = class_resolveclassmethod(p->vftbl->class,
656 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
663 /* process all properties stored in the internal table */
665 for (pe = list_first(list_properties); pe != NULL;
666 pe = list_next(list_properties, pe)) {
667 /* add to the Java system properties */
669 key = javastring_new_from_utf_string(pe->key);
670 value = javastring_new_from_utf_string(pe->value);
672 (void) vm_call_method(m, (java_handle_t *) p, key, value);
675 #endif /* defined(ENABLE_JAVASE) */
679 * These are local overrides for various environment variables in Emacs.
680 * Please do not remove this and leave it at the end of the file, where
681 * Emacs will automagically detect them.
682 * ---------------------------------------------------------------------
685 * indent-tabs-mode: t