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"
47 #include "vm/global.h" /* required by java_lang_String.h */
48 #include "native/include/java_lang_String.h"
50 #include "toolbox/list.h"
51 #include "toolbox/util.h"
53 #include "vm/properties.h"
54 #include "vm/stringlocal.h"
57 #include "vm/jit/asmpart.h"
59 #include "vmcore/method.h"
60 #include "vmcore/options.h"
63 /* internal property structure ************************************************/
65 typedef struct list_properties_entry_t list_properties_entry_t;
67 struct list_properties_entry_t {
74 /* global variables ***********************************************************/
76 static list_t *list_properties = NULL;
79 /* properties_init *************************************************************
81 Initialize the properties list and fill the list with default
84 *******************************************************************************/
86 void properties_init(void)
88 list_properties = list_create(OFFSET(list_properties_entry_t, linkage));
92 /* properties_set **************************************************************
94 Fill the properties list with default values.
96 *******************************************************************************/
98 void properties_set(void)
104 char *boot_class_path;
106 #if defined(ENABLE_JAVASE)
108 char *boot_library_path;
110 # if defined(WITH_CLASSPATH_GNU)
118 struct utsname *utsnamebuf;
120 char *java_library_path;
124 #if defined(WITH_JRE_LAYOUT)
125 /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
127 p = MNEW(char, 4096);
129 if (readlink("/proc/self/exe", p, 4095) == -1)
130 vm_abort("properties_set: readlink failed: %s\n", strerror(errno));
132 /* Get the path of the current executable. */
136 # if defined(WITH_CLASSPATH_GNU)
140 len = strlen(path) + strlen("/..") + strlen("0");
142 java_home = MNEW(char, len);
144 strcpy(java_home, p);
145 strcat(java_home, "/..");
147 /* Set the path to Java core native libraries. */
149 len = strlen(cacao_prefix) + strlen("/lib/classpath") + strlen("0");
151 boot_library_path = MNEW(char, len);
153 strcpy(boot_library_path, java_home);
154 strcat(boot_library_path, "/lib/classpath");
156 # elif defined(WITH_CLASSPATH_SUN)
158 /* Find correct java.home. We check if there is a JRE
161 /* NOTE: We use the server VM here as it should be available on
162 all architectures. */
166 strlen("/../jre/lib/"JAVA_ARCH"/server/libjvm.so") +
169 java_home = MNEW(char, len);
171 strcpy(java_home, p);
172 strcat(java_home, "/../jre/lib/"JAVA_ARCH"/server/libjvm.so");
174 /* Check if that libjvm.so exists. */
176 if (access(java_home, F_OK) == 0) {
177 /* Yes, we add /jre to java.home. */
179 strcpy(java_home, p);
180 strcat(java_home, "/../jre");
183 /* No, java.home is parent directory. */
185 strcpy(java_home, p);
186 strcat(java_home, "/..");
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_CLASSPATH_GNU)
211 boot_library_path = CLASSPATH_LIBDIR"/classpath";
213 # elif defined(WITH_CLASSPATH_SUN)
215 boot_library_path = CLASSPATH_LIBDIR;
217 # elif defined(WITH_CLASSPATH_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(WITH_JRE_LAYOUT)
238 # if defined(WITH_CLASSPATH_GNU)
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_CLASSPATH_SUN)
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_CLASSPATH_GNU)
293 strlen(CACAO_VM_ZIP) +
295 strlen(CLASSPATH_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, CLASSPATH_CLASSES);
304 # elif defined(WITH_CLASSPATH_SUN)
306 /* This is the bootclasspath taken from HotSpot (see
307 hotspot/src/share/vm/runtime/os.cpp
308 (os::set_boot_path)). */
311 strlen(CLASSPATH_PREFIX"/lib/resources.jar:") +
312 strlen(CLASSPATH_PREFIX"/lib/rt.jar:") +
313 strlen(CLASSPATH_PREFIX"/lib/sunrsasign.jar:") +
314 strlen(CLASSPATH_PREFIX"/lib/jsse.jar:") +
315 strlen(CLASSPATH_PREFIX"/lib/jce.jar:") +
316 strlen(CLASSPATH_PREFIX"/lib/charsets.jar:") +
317 strlen(CLASSPATH_PREFIX"/classes") +
320 boot_class_path = MNEW(char, len);
322 strcpy(boot_class_path, CLASSPATH_PREFIX"/lib/resources.jar:");
323 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/rt.jar:");
324 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/sunrsasign.jar:");
325 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/jsse.jar:");
326 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/jce.jar:");
327 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/charsets.jar:");
328 strcat(boot_class_path, CLASSPATH_PREFIX"/classes");
330 # elif defined(WITH_CLASSPATH_CLDC1_1)
333 strlen(CLASSPATH_CLASSES) +
336 boot_class_path = MNEW(char, len);
338 strcpy(boot_class_path, CLASSPATH_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", "CACAO Team");
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_CLASSPATH_GNU)
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 # if defined(WITH_STATIC_CLASSPATH)
417 properties_add("gnu.classpath.boot.library.path", ".");
418 properties_add("java.library.path" , ".");
420 properties_add("gnu.classpath.boot.library.path", boot_library_path);
422 /* Get and set java.library.path. */
424 java_library_path = getenv("LD_LIBRARY_PATH");
426 if (java_library_path == NULL)
427 java_library_path = "";
429 properties_add("java.library.path", java_library_path);
432 properties_add("java.io.tmpdir", "/tmp");
434 # if defined(ENABLE_INTRP)
436 properties_add("gnu.java.compiler.name", "cacao.intrp");
441 properties_add("gnu.java.compiler.name", "cacao.jit");
444 /* set the java.ext.dirs property */
446 len = strlen(java_home) + strlen("/jre/lib/ext") + strlen("0");
448 extdirs = MNEW(char, len);
450 strcpy(extdirs, java_home);
451 strcat(extdirs, "/jre/lib/ext");
453 properties_add("java.ext.dirs", extdirs);
455 properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed");
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 defined(WITH_STATIC_CLASSPATH)
474 /* This is just for debugging purposes and can cause troubles in
477 properties_add("gnu.cpu.endian", "unknown");
479 # if WORDS_BIGENDIAN == 1
480 properties_add("gnu.cpu.endian", "big");
482 properties_add("gnu.cpu.endian", "little");
486 properties_add("file.separator", "/");
487 properties_add("path.separator", ":");
488 properties_add("line.separator", "\n");
490 properties_add("user.name", env_user ? env_user : "null");
491 properties_add("user.home", env_home ? env_home : "null");
492 properties_add("user.dir", cwd ? cwd : "null");
496 if (env_lang != NULL) {
497 /* get the local stuff from the environment */
499 if (strlen(env_lang) <= 2) {
500 properties_add("user.language", env_lang);
503 if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
504 lang = MNEW(char, 3);
505 strncpy(lang, (char *) &env_lang[0], 2);
508 country = MNEW(char, 3);
509 strncpy(country, (char *) &env_lang[3], 2);
512 properties_add("user.language", lang);
513 properties_add("user.country", country);
518 /* if no default locale was specified, use `en_US' */
520 properties_add("user.language", "en");
521 properties_add("user.country", "US");
524 # elif defined(WITH_CLASSPATH_SUN)
526 /* Actually this property is set by OpenJDK, but we need it in
527 nativevm_preinit(). */
529 properties_add("sun.boot.library.path", boot_library_path);
533 # error unknown classpath configuration
537 #elif defined(ENABLE_JAVAME_CLDC1_1)
539 properties_add("microedition.configuration", "CLDC-1.1");
540 properties_add("microedition.platform", "generic");
541 properties_add("microedition.encoding", "ISO8859_1");
542 properties_add("microedition.profiles", "");
546 # error unknown Java configuration
552 /* properties_add **************************************************************
554 Adds a property entry to the internal property list. If there's
555 already an entry with the same key, replace it.
557 *******************************************************************************/
559 void properties_add(char *key, char *value)
561 list_properties_entry_t *pe;
563 /* search for the entry */
565 for (pe = list_first_unsynced(list_properties); pe != NULL;
566 pe = list_next_unsynced(list_properties, pe)) {
567 if (strcmp(pe->key, key) == 0) {
568 /* entry was found, replace the value */
576 /* entry was not found, insert a new one */
578 pe = NEW(list_properties_entry_t);
583 list_add_last_unsynced(list_properties, pe);
587 /* properties_get **************************************************************
589 Get a property entry from the internal property list.
591 *******************************************************************************/
593 char *properties_get(char *key)
595 list_properties_entry_t *pe;
597 for (pe = list_first_unsynced(list_properties); pe != NULL;
598 pe = list_next_unsynced(list_properties, pe)) {
599 if (strcmp(pe->key, key) == 0)
607 /* properties_system_add *******************************************************
609 Adds a given property to the Java system properties.
611 *******************************************************************************/
613 void properties_system_add(java_handle_t *p, char *key, char *value)
619 /* search for method to add properties */
621 m = class_resolveclassmethod(p->vftbl->class,
623 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
630 /* add to the Java system properties */
632 k = javastring_new_from_utf_string(key);
633 v = javastring_new_from_utf_string(value);
635 (void) vm_call_method(m, p, k, v);
639 /* properties_system_add_all ***************************************************
641 Adds all properties from the properties list to the Java system
645 p.... is actually a java_util_Properties structure
647 *******************************************************************************/
649 #if defined(ENABLE_JAVASE)
650 void properties_system_add_all(java_handle_t *p)
652 list_properties_entry_t *pe;
655 java_handle_t *value;
657 /* search for method to add properties */
659 m = class_resolveclassmethod(p->vftbl->class,
661 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
668 /* process all properties stored in the internal table */
670 for (pe = list_first(list_properties); pe != NULL;
671 pe = list_next(list_properties, pe)) {
672 /* add to the Java system properties */
674 key = javastring_new_from_utf_string(pe->key);
675 value = javastring_new_from_utf_string(pe->value);
677 (void) vm_call_method(m, (java_handle_t *) p, key, value);
680 #endif /* defined(ENABLE_JAVASE) */
684 * These are local overrides for various environment variables in Emacs.
685 * Please do not remove this and leave it at the end of the file, where
686 * Emacs will automagically detect them.
687 * ---------------------------------------------------------------------
690 * indent-tabs-mode: t