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 8403 2007-08-22 19:59:32Z 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)
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(path) + 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(cacao_prefix) + 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 # if defined(WITH_STATIC_CLASSPATH)
419 properties_add("gnu.classpath.boot.library.path", ".");
420 properties_add("java.library.path" , ".");
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);
434 properties_add("java.io.tmpdir", "/tmp");
436 # if defined(ENABLE_INTRP)
438 properties_add("gnu.java.compiler.name", "cacao.intrp");
443 properties_add("gnu.java.compiler.name", "cacao.jit");
446 /* set the java.ext.dirs property */
448 len = strlen(java_home) + strlen("/jre/lib/ext") + strlen("0");
450 extdirs = MNEW(char, len);
452 strcpy(extdirs, java_home);
453 strcat(extdirs, "/jre/lib/ext");
455 properties_add("java.ext.dirs", extdirs);
457 properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed");
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 defined(WITH_STATIC_CLASSPATH)
476 /* This is just for debugging purposes and can cause troubles in
479 properties_add("gnu.cpu.endian", "unknown");
481 # if WORDS_BIGENDIAN == 1
482 properties_add("gnu.cpu.endian", "big");
484 properties_add("gnu.cpu.endian", "little");
488 properties_add("file.separator", "/");
489 properties_add("path.separator", ":");
490 properties_add("line.separator", "\n");
492 properties_add("user.name", env_user ? env_user : "null");
493 properties_add("user.home", env_home ? env_home : "null");
494 properties_add("user.dir", cwd ? cwd : "null");
498 if (env_lang != NULL) {
499 /* get the local stuff from the environment */
501 if (strlen(env_lang) <= 2) {
502 properties_add("user.language", env_lang);
505 if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
506 lang = MNEW(char, 3);
507 strncpy(lang, (char *) &env_lang[0], 2);
510 country = MNEW(char, 3);
511 strncpy(country, (char *) &env_lang[3], 2);
514 properties_add("user.language", lang);
515 properties_add("user.country", country);
520 /* if no default locale was specified, use `en_US' */
522 properties_add("user.language", "en");
523 properties_add("user.country", "US");
526 # elif defined(WITH_CLASSPATH_SUN)
528 /* Actually this property is set by OpenJDK, but we need it in
529 nativevm_preinit(). */
531 properties_add("sun.boot.library.path", boot_library_path);
535 # error unknown classpath configuration
539 #elif defined(ENABLE_JAVAME_CLDC1_1)
541 properties_add("microedition.configuration", "CLDC-1.1");
542 properties_add("microedition.platform", "generic");
543 properties_add("microedition.encoding", "ISO8859_1");
544 properties_add("microedition.profiles", "");
548 # error unknown Java configuration
554 /* properties_add **************************************************************
556 Adds a property entry to the internal property list. If there's
557 already an entry with the same key, replace it.
559 *******************************************************************************/
561 void properties_add(char *key, char *value)
563 list_properties_entry_t *pe;
565 /* search for the entry */
567 for (pe = list_first_unsynced(list_properties); pe != NULL;
568 pe = list_next_unsynced(list_properties, pe)) {
569 if (strcmp(pe->key, key) == 0) {
570 /* entry was found, replace the value */
578 /* entry was not found, insert a new one */
580 pe = NEW(list_properties_entry_t);
585 list_add_last_unsynced(list_properties, pe);
589 /* properties_get **************************************************************
591 Get a property entry from the internal property list.
593 *******************************************************************************/
595 char *properties_get(char *key)
597 list_properties_entry_t *pe;
599 for (pe = list_first_unsynced(list_properties); pe != NULL;
600 pe = list_next_unsynced(list_properties, pe)) {
601 if (strcmp(pe->key, key) == 0)
609 /* properties_system_add *******************************************************
611 Adds a given property to the Java system properties.
613 *******************************************************************************/
615 void properties_system_add(java_handle_t *p, char *key, char *value)
621 /* search for method to add properties */
623 m = class_resolveclassmethod(p->vftbl->class,
625 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
632 /* add to the Java system properties */
634 k = javastring_new_from_utf_string(key);
635 v = javastring_new_from_utf_string(value);
637 (void) vm_call_method(m, p, k, v);
641 /* properties_system_add_all ***************************************************
643 Adds all properties from the properties list to the Java system
647 p.... is actually a java_util_Properties structure
649 *******************************************************************************/
651 #if defined(ENABLE_JAVASE)
652 void properties_system_add_all(java_handle_t *p)
654 list_properties_entry_t *pe;
657 java_handle_t *value;
659 /* search for method to add properties */
661 m = class_resolveclassmethod(p->vftbl->class,
663 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
670 /* process all properties stored in the internal table */
672 for (pe = list_first(list_properties); pe != NULL;
673 pe = list_next(list_properties, pe)) {
674 /* add to the Java system properties */
676 key = javastring_new_from_utf_string(pe->key);
677 value = javastring_new_from_utf_string(pe->value);
679 (void) vm_call_method(m, (java_handle_t *) p, key, value);
682 #endif /* defined(ENABLE_JAVASE) */
686 * These are local overrides for various environment variables in Emacs.
687 * Please do not remove this and leave it at the end of the file, where
688 * Emacs will automagically detect them.
689 * ---------------------------------------------------------------------
692 * indent-tabs-mode: t