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 8399 2007-08-22 18:24:23Z twisti $
36 #include <sys/utsname.h>
40 #include "mm/memory.h"
42 #include "native/jni.h"
44 #include "vm/global.h" /* required by java_lang_String.h */
45 #include "native/include/java_lang_String.h"
47 #include "toolbox/list.h"
48 #include "toolbox/util.h"
50 #include "vm/properties.h"
51 #include "vm/stringlocal.h"
54 #include "vm/jit/asmpart.h"
56 #include "vmcore/method.h"
57 #include "vmcore/options.h"
60 /* internal property structure ************************************************/
62 typedef struct list_properties_entry_t list_properties_entry_t;
64 struct list_properties_entry_t {
71 /* global variables ***********************************************************/
73 static list_t *list_properties = NULL;
76 /* properties_init *************************************************************
78 Initialize the properties list and fill the list with default
81 *******************************************************************************/
83 void properties_init(void)
85 list_properties = list_create(OFFSET(list_properties_entry_t, linkage));
89 /* properties_set **************************************************************
91 Fill the properties list with default values.
93 *******************************************************************************/
95 void properties_set(void)
97 #if defined(ENABLE_JAVASE)
102 char *boot_library_path;
103 char *boot_class_path;
106 # if defined(WITH_CLASSPATH_GNU)
114 struct utsname *utsnamebuf;
116 char *java_library_path;
120 #if defined(WITH_JRE_LAYOUT)
121 /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
123 p = MNEW(char, 4096);
125 if (readlink("/proc/self/exe", p, 4095) == -1)
126 vm_abort("properties_set: readlink failed: %s\n", strerror(errno));
128 /* Get the path of the current executable. */
132 # if defined(WITH_CLASSPATH_GNU)
136 len = strlen(path) + strlen("/..") + strlen("0");
138 java_home = MNEW(char, len);
140 strcpy(java_home, p);
141 strcat(java_home, "/..");
143 /* Set the path to Java core native libraries. */
145 len = strlen(cacao_prefix) + strlen("/lib/classpath") + strlen("0");
147 boot_library_path = MNEW(char, len);
149 strcpy(boot_library_path, java_home);
150 strcat(boot_library_path, "/lib/classpath");
152 # elif defined(WITH_CLASSPATH_SUN)
154 /* Find correct java.home. We check if there is a JRE
157 /* NOTE: We use the server VM here as it should be available on
158 all architectures. */
162 strlen("/../jre/lib/"JAVA_ARCH"/server/libjvm.so") +
165 java_home = MNEW(char, len);
167 strcpy(java_home, p);
168 strcat(java_home, "/../jre/lib/"JAVA_ARCH"/server/libjvm.so");
170 /* Check if that libjvm.so exists. */
172 if (access(java_home, F_OK) == 0) {
173 /* Yes, we add /jre to java.home. */
175 strcpy(java_home, p);
176 strcat(java_home, "/../jre");
179 /* No, java.home is parent directory. */
181 strcpy(java_home, p);
182 strcat(java_home, "/..");
186 # error unknown classpath configuration
194 java_home = CACAO_PREFIX;
196 # if defined(WITH_CLASSPATH_GNU)
197 boot_library_path = CLASSPATH_LIBDIR"/classpath";
199 boot_library_path = CLASSPATH_LIBDIR;
203 properties_add("java.home", java_home);
205 /* Set the bootclasspath. */
207 p = getenv("BOOTCLASSPATH");
210 boot_class_path = MNEW(char, strlen(p) + strlen("0"));
211 strcpy(boot_class_path, p);
214 #if defined(WITH_JRE_LAYOUT)
215 # if defined(WITH_CLASSPATH_GNU)
218 strlen(java_home) + strlen("/share/cacao/vm.zip:") +
219 strlen(java_home) + strlen("/share/classpath/glibj.zip") +
222 boot_class_path = MNEW(char, len);
224 strcpy(boot_class_path, java_home);
225 strcat(boot_class_path, "/share/cacao/vm.zip");
226 strcat(boot_class_path, ":");
227 strcat(boot_class_path, java_home);
228 strcat(boot_class_path, "/share/classpath/glibj.zip");
230 # elif defined(WITH_CLASSPATH_SUN)
232 /* This is the bootclasspath taken from HotSpot (see
233 hotspot/src/share/vm/runtime/os.cpp
234 (os::set_boot_path)). */
237 strlen(java_home) + strlen("/lib/resources.jar:") +
238 strlen(java_home) + strlen("/lib/rt.jar:") +
239 strlen(java_home) + strlen("/lib/sunrsasign.jar:") +
240 strlen(java_home) + strlen("/lib/jsse.jar:") +
241 strlen(java_home) + strlen("/lib/jce.jar:") +
242 strlen(java_home) + strlen("/lib/charsets.jar:") +
243 strlen(java_home) + strlen("/classes") +
246 boot_class_path = MNEW(char, len);
248 strcpy(boot_class_path, java_home);
249 strcat(boot_class_path, "/lib/resources.jar:");
250 strcat(boot_class_path, java_home);
251 strcat(boot_class_path, "/lib/rt.jar:");
252 strcat(boot_class_path, java_home);
253 strcat(boot_class_path, "/lib/sunrsasign.jar:");
254 strcat(boot_class_path, java_home);
255 strcat(boot_class_path, "/lib/jsse.jar:");
256 strcat(boot_class_path, java_home);
257 strcat(boot_class_path, "/lib/jce.jar:");
258 strcat(boot_class_path, java_home);
259 strcat(boot_class_path, "/lib/charsets.jar:");
260 strcat(boot_class_path, java_home);
261 strcat(boot_class_path, "/classes");
264 # error unknown classpath configuration
267 # if defined(WITH_CLASSPATH_GNU)
270 strlen(CACAO_VM_ZIP) +
272 strlen(CLASSPATH_CLASSES) +
275 boot_class_path = MNEW(char, len);
277 strcpy(boot_class_path, CACAO_VM_ZIP);
278 strcat(boot_class_path, ":");
279 strcat(boot_class_path, CLASSPATH_CLASSES);
281 # elif defined(WITH_CLASSPATH_SUN)
283 /* This is the bootclasspath taken from HotSpot (see
284 hotspot/src/share/vm/runtime/os.cpp
285 (os::set_boot_path)). */
288 strlen(CLASSPATH_PREFIX"/lib/resources.jar:") +
289 strlen(CLASSPATH_PREFIX"/lib/rt.jar:") +
290 strlen(CLASSPATH_PREFIX"/lib/sunrsasign.jar:") +
291 strlen(CLASSPATH_PREFIX"/lib/jsse.jar:") +
292 strlen(CLASSPATH_PREFIX"/lib/jce.jar:") +
293 strlen(CLASSPATH_PREFIX"/lib/charsets.jar:") +
294 strlen(CLASSPATH_PREFIX"/classes") +
297 boot_class_path = MNEW(char, len);
299 strcpy(boot_class_path, CLASSPATH_PREFIX"/lib/resources.jar:");
300 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/rt.jar:");
301 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/sunrsasign.jar:");
302 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/jsse.jar:");
303 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/jce.jar:");
304 strcat(boot_class_path, CLASSPATH_PREFIX"/lib/charsets.jar:");
305 strcat(boot_class_path, CLASSPATH_PREFIX"/classes");
307 # elif defined(WITH_CLASSPATH_CLDC1_1)
310 strlen(CLASSPATH_CLASSES) +
313 boot_class_path = MNEW(char, len);
315 strcat(boot_class_path, CLASSPATH_CLASSES);
318 # error unknown classpath configuration
323 properties_add("java.boot.class.path", boot_class_path);
324 properties_add("sun.boot.class.path", boot_class_path);
326 /* Set the classpath. */
328 p = getenv("CLASSPATH");
331 class_path = MNEW(char, strlen(p) + strlen("0"));
332 strcpy(class_path, p);
335 class_path = MNEW(char, strlen(".") + strlen("0"));
336 strcpy(class_path, ".");
339 properties_add("java.class.path", class_path);
341 #if defined(ENABLE_JAVASE)
343 /* get properties from system */
345 p = getenv("JAVA_HOME");
347 /* fill in system properties */
349 properties_add("java.vm.specification.version", "1.0");
350 properties_add("java.vm.specification.vendor", "Sun Microsystems Inc.");
351 properties_add("java.vm.specification.name", "Java Virtual Machine Specification");
352 properties_add("java.vm.version", VERSION);
353 properties_add("java.vm.vendor", "CACAO Team");
354 properties_add("java.vm.name", "CACAO");
356 # if defined(ENABLE_INTRP)
358 /* XXX We don't support java.lang.Compiler */
359 /* properties_add("java.compiler", "cacao.intrp"); */
360 properties_add("java.vm.info", "interpreted mode");
365 /* XXX We don't support java.lang.Compiler */
366 /* properties_add("java.compiler", "cacao.jit"); */
367 properties_add("java.vm.info", "JIT mode");
370 # if defined(WITH_CLASSPATH_GNU)
372 /* Get properties from system. */
376 env_user = getenv("USER");
377 env_home = getenv("HOME");
378 env_lang = getenv("LANG");
380 utsnamebuf = NEW(struct utsname);
384 properties_add("java.runtime.version", VERSION);
385 properties_add("java.runtime.name", "CACAO");
387 properties_add("java.specification.version", "1.5");
388 properties_add("java.specification.vendor", "Sun Microsystems Inc.");
389 properties_add("java.specification.name", "Java Platform API Specification");
391 properties_add("java.version", JAVA_VERSION);
392 properties_add("java.vendor", "GNU Classpath");
393 properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/");
395 properties_add("java.class.version", CLASS_VERSION);
397 # if defined(WITH_STATIC_CLASSPATH)
398 properties_add("gnu.classpath.boot.library.path", ".");
399 properties_add("java.library.path" , ".");
401 properties_add("gnu.classpath.boot.library.path", boot_library_path);
403 /* Get and set java.library.path. */
405 java_library_path = getenv("LD_LIBRARY_PATH");
407 if (java_library_path == NULL)
408 java_library_path = "";
410 properties_add("java.library.path", java_library_path);
413 properties_add("java.io.tmpdir", "/tmp");
415 # if defined(ENABLE_INTRP)
417 properties_add("gnu.java.compiler.name", "cacao.intrp");
422 properties_add("gnu.java.compiler.name", "cacao.jit");
425 /* set the java.ext.dirs property */
427 len = strlen(java_home) + strlen("/jre/lib/ext") + strlen("0");
429 extdirs = MNEW(char, len);
431 strcpy(extdirs, java_home);
432 strcat(extdirs, "/jre/lib/ext");
434 properties_add("java.ext.dirs", extdirs);
436 properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed");
438 # if defined(DISABLE_GC)
439 /* When we disable the GC, we mmap the whole heap to a specific
440 address, so we can compare call traces. For this reason we have
441 to add the same properties on different machines, otherwise
442 more memory may be allocated (e.g. strlen("i386")
443 vs. strlen("alpha"). */
445 properties_add("os.arch", "unknown");
446 properties_add("os.name", "unknown");
447 properties_add("os.version", "unknown");
449 properties_add("os.arch", JAVA_ARCH);
450 properties_add("os.name", utsnamebuf->sysname);
451 properties_add("os.version", utsnamebuf->release);
454 # if defined(WITH_STATIC_CLASSPATH)
455 /* This is just for debugging purposes and can cause troubles in
458 properties_add("gnu.cpu.endian", "unknown");
460 # if WORDS_BIGENDIAN == 1
461 properties_add("gnu.cpu.endian", "big");
463 properties_add("gnu.cpu.endian", "little");
467 properties_add("file.separator", "/");
468 properties_add("path.separator", ":");
469 properties_add("line.separator", "\n");
471 properties_add("user.name", env_user ? env_user : "null");
472 properties_add("user.home", env_home ? env_home : "null");
473 properties_add("user.dir", cwd ? cwd : "null");
477 if (env_lang != NULL) {
478 /* get the local stuff from the environment */
480 if (strlen(env_lang) <= 2) {
481 properties_add("user.language", env_lang);
484 if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
485 lang = MNEW(char, 3);
486 strncpy(lang, (char *) &env_lang[0], 2);
489 country = MNEW(char, 3);
490 strncpy(country, (char *) &env_lang[3], 2);
493 properties_add("user.language", lang);
494 properties_add("user.country", country);
499 /* if no default locale was specified, use `en_US' */
501 properties_add("user.language", "en");
502 properties_add("user.country", "US");
505 # elif defined(WITH_CLASSPATH_SUN)
511 # error unknown classpath configuration
515 #elif defined(ENABLE_JAVAME_CLDC1_1)
517 properties_add("microedition.configuration", "CLDC-1.1");
518 properties_add("microedition.platform", "generic");
519 properties_add("microedition.encoding", "ISO8859_1");
520 properties_add("microedition.profiles", "");
524 # error unknown Java configuration
530 /* properties_add **************************************************************
532 Adds a property entry to the internal property list. If there's
533 already an entry with the same key, replace it.
535 *******************************************************************************/
537 void properties_add(char *key, char *value)
539 list_properties_entry_t *pe;
541 /* search for the entry */
543 for (pe = list_first_unsynced(list_properties); pe != NULL;
544 pe = list_next_unsynced(list_properties, pe)) {
545 if (strcmp(pe->key, key) == 0) {
546 /* entry was found, replace the value */
554 /* entry was not found, insert a new one */
556 pe = NEW(list_properties_entry_t);
561 list_add_last_unsynced(list_properties, pe);
565 /* properties_get **************************************************************
567 Get a property entry from the internal property list.
569 *******************************************************************************/
571 char *properties_get(char *key)
573 list_properties_entry_t *pe;
575 for (pe = list_first_unsynced(list_properties); pe != NULL;
576 pe = list_next_unsynced(list_properties, pe)) {
577 if (strcmp(pe->key, key) == 0)
585 /* properties_system_add *******************************************************
587 Adds a given property to the Java system properties.
589 *******************************************************************************/
591 void properties_system_add(java_handle_t *p, char *key, char *value)
597 /* search for method to add properties */
599 m = class_resolveclassmethod(p->vftbl->class,
601 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
608 /* add to the Java system properties */
610 k = javastring_new_from_utf_string(key);
611 v = javastring_new_from_utf_string(value);
613 (void) vm_call_method(m, p, k, v);
617 /* properties_system_add_all ***************************************************
619 Adds all properties from the properties list to the Java system
623 p.... is actually a java_util_Properties structure
625 *******************************************************************************/
627 #if defined(ENABLE_JAVASE)
628 void properties_system_add_all(java_handle_t *p)
630 list_properties_entry_t *pe;
633 java_handle_t *value;
635 /* search for method to add properties */
637 m = class_resolveclassmethod(p->vftbl->class,
639 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
646 /* process all properties stored in the internal table */
648 for (pe = list_first(list_properties); pe != NULL;
649 pe = list_next(list_properties, pe)) {
650 /* add to the Java system properties */
652 key = javastring_new_from_utf_string(pe->key);
653 value = javastring_new_from_utf_string(pe->value);
655 (void) vm_call_method(m, (java_handle_t *) p, key, value);
658 #endif /* defined(ENABLE_JAVASE) */
662 * These are local overrides for various environment variables in Emacs.
663 * Please do not remove this and leave it at the end of the file, where
664 * Emacs will automagically detect them.
665 * ---------------------------------------------------------------------
668 * indent-tabs-mode: t