* configure.ac (AC_CHECK_FUNCS): Added access.
[cacao.git] / src / vm / properties.c
1 /* src/vm/properties.c - handling commandline properties
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02110-1301, USA.
24
25    $Id: properties.c 8381 2007-08-21 13:00:21Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <time.h>
35 #include <unistd.h>
36 #include <sys/utsname.h>
37
38 #include "vm/types.h"
39
40 #include "mm/memory.h"
41
42 #include "native/jni.h"
43
44 #include "vm/global.h"                      /* required by java_lang_String.h */
45 #include "native/include/java_lang_String.h"
46
47 #include "toolbox/list.h"
48 #include "toolbox/util.h"
49
50 #include "vm/properties.h"
51 #include "vm/stringlocal.h"
52 #include "vm/vm.h"
53
54 #include "vm/jit/asmpart.h"
55
56 #include "vmcore/method.h"
57 #include "vmcore/options.h"
58
59
60 /* internal property structure ************************************************/
61
62 typedef struct list_properties_entry list_properties_entry;
63
64 struct list_properties_entry {
65         char       *key;
66         char       *value;
67         listnode_t  linkage;
68 };
69
70
71 /* global variables ***********************************************************/
72
73 static list_t *list_properties = NULL;
74
75
76 /* properties_init *************************************************************
77
78    Initialize the properties list and fill the list with default
79    values.
80
81 *******************************************************************************/
82
83 bool properties_init(void)
84 {
85 #if defined(ENABLE_JAVASE)
86         char           *env_java_home;
87         char           *java_home;
88         s4              len;
89
90 # if defined(WITH_CLASSPATH_GNU)
91         char           *cwd;
92         char           *env_user;
93         char           *env_home;
94         char           *env_lang;
95         char           *extdirs;
96         char           *lang;
97         char           *country;
98         struct utsname *utsnamebuf;
99 # endif
100 #endif
101
102         /* create the properties list */
103
104         list_properties = list_create(OFFSET(list_properties_entry, linkage));
105
106 #if defined(ENABLE_JAVASE)
107
108         /* get properties from system */
109
110         env_java_home = getenv("JAVA_HOME");
111
112         /* set JAVA_HOME to default prefix if not defined */
113
114         if (env_java_home == NULL)
115                 env_java_home = cacao_prefix;
116
117         /* fill in system properties */
118
119         /* add /jre to java.home property */
120
121         len = strlen(env_java_home) + strlen("/jre") + strlen("0");
122
123         java_home = MNEW(char, len);
124
125         strcpy(java_home, env_java_home);
126         strcat(java_home, "/jre");
127
128         properties_add("java.home", java_home);
129
130         properties_add("java.vm.specification.version", "1.0");
131         properties_add("java.vm.specification.vendor", "Sun Microsystems Inc.");
132         properties_add("java.vm.specification.name", "Java Virtual Machine Specification");
133         properties_add("java.vm.version", VERSION);
134         properties_add("java.vm.vendor", "CACAO Team");
135         properties_add("java.vm.name", "CACAO");
136
137 # if defined(ENABLE_INTRP)
138         if (opt_intrp) {
139                 /* XXX We don't support java.lang.Compiler */
140 /*              properties_add("java.compiler", "cacao.intrp"); */
141                 properties_add("java.vm.info", "interpreted mode");
142         }
143         else
144 # endif
145         {
146                 /* XXX We don't support java.lang.Compiler */
147 /*              properties_add("java.compiler", "cacao.jit"); */
148                 properties_add("java.vm.info", "JIT mode");
149         }
150
151 # if defined(WITH_CLASSPATH_GNU)
152
153         /* get properties from system */
154
155         cwd      = _Jv_getcwd();
156
157         env_user = getenv("USER");
158         env_home = getenv("HOME");
159         env_lang = getenv("LANG");
160
161         utsnamebuf = NEW(struct utsname);
162
163         uname(utsnamebuf);
164
165         properties_add("java.runtime.version", VERSION);
166         properties_add("java.runtime.name", "CACAO");
167
168         properties_add("java.specification.version", "1.5");
169         properties_add("java.specification.vendor", "Sun Microsystems Inc.");
170         properties_add("java.specification.name", "Java Platform API Specification");
171
172         properties_add("java.version", JAVA_VERSION);
173         properties_add("java.vendor", "GNU Classpath");
174         properties_add("java.vendor.url", "http://www.gnu.org/software/classpath/");
175
176         properties_add("java.class.path", _Jv_classpath);
177         properties_add("java.class.version", CLASS_VERSION);
178
179         /* Set bootclasspath properties. One for GNU classpath and the
180            other for compatibility with Sun (required by most
181            applications). */
182
183         properties_add("java.boot.class.path", _Jv_bootclasspath);
184         properties_add("sun.boot.class.path", _Jv_bootclasspath);
185
186 #  if defined(WITH_STATIC_CLASSPATH)
187         properties_add("gnu.classpath.boot.library.path", ".");
188         properties_add("java.library.path" , ".");
189 #  else
190         /* fill gnu.classpath.boot.library.path with GNU Classpath library
191        path */
192
193         properties_add("gnu.classpath.boot.library.path", classpath_libdir);
194         properties_add("java.library.path", _Jv_java_library_path);
195 #  endif
196
197         properties_add("java.io.tmpdir", "/tmp");
198
199 #  if defined(ENABLE_INTRP)
200         if (opt_intrp) {
201                 properties_add("gnu.java.compiler.name", "cacao.intrp");
202         }
203         else
204 #  endif
205         {
206                 properties_add("gnu.java.compiler.name", "cacao.jit");
207         }
208
209         /* set the java.ext.dirs property */
210
211         len = strlen(env_java_home) + strlen("/jre/lib/ext") + strlen("0");
212
213         extdirs = MNEW(char, len);
214
215         strcpy(extdirs, env_java_home);
216         strcat(extdirs, "/jre/lib/ext");
217
218         properties_add("java.ext.dirs", extdirs);
219
220         properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed");
221
222 #  if defined(DISABLE_GC)
223         /* When we disable the GC, we mmap the whole heap to a specific
224            address, so we can compare call traces. For this reason we have
225            to add the same properties on different machines, otherwise
226            more memory may be allocated (e.g. strlen("i386")
227            vs. strlen("alpha"). */
228
229         properties_add("os.arch", "unknown");
230         properties_add("os.name", "unknown");
231         properties_add("os.version", "unknown");
232 #  else
233         properties_add("os.arch", JAVA_ARCH);
234         properties_add("os.name", utsnamebuf->sysname);
235         properties_add("os.version", utsnamebuf->release);
236 #  endif
237
238 #  if defined(WITH_STATIC_CLASSPATH)
239         /* This is just for debugging purposes and can cause troubles in
240        GNU Classpath. */
241
242         properties_add("gnu.cpu.endian", "unknown");
243 #  else
244 #   if WORDS_BIGENDIAN == 1
245         properties_add("gnu.cpu.endian", "big");
246 #   else
247         properties_add("gnu.cpu.endian", "little");
248 #   endif
249 #  endif
250
251         properties_add("file.separator", "/");
252         properties_add("path.separator", ":");
253         properties_add("line.separator", "\n");
254
255         properties_add("user.name", env_user ? env_user : "null");
256         properties_add("user.home", env_home ? env_home : "null");
257         properties_add("user.dir", cwd ? cwd : "null");
258
259         /* get locale */
260
261         if (env_lang != NULL) {
262                 /* get the local stuff from the environment */
263
264                 if (strlen(env_lang) <= 2) {
265                         properties_add("user.language", env_lang);
266                 }
267                 else {
268                         if ((env_lang[2] == '_') && (strlen(env_lang) >= 5)) {
269                                 lang = MNEW(char, 3);
270                                 strncpy(lang, (char *) &env_lang[0], 2);
271                                 lang[2] = '\0';
272
273                                 country = MNEW(char, 3);
274                                 strncpy(country, (char *) &env_lang[3], 2);
275                                 country[2] = '\0';
276
277                                 properties_add("user.language", lang);
278                                 properties_add("user.country", country);
279                         }
280                 }
281         }
282         else {
283                 /* if no default locale was specified, use `en_US' */
284
285                 properties_add("user.language", "en");
286                 properties_add("user.country", "US");
287         }
288
289 # elif defined(WITH_CLASSPATH_SUN)
290
291         /* Find correct java.home.  We check if there is a JRE
292            co-located. */
293
294         /* NOTE: We use the server VM here as it should be available on
295            all architectures. */
296
297         len =
298                 strlen(env_java_home) +
299                 strlen("/jre/lib/"JAVA_ARCH"/server/libjvm.so") +
300                 strlen("0");
301
302         java_home = MNEW(char, len);
303
304         strcpy(java_home, env_java_home);
305         strcat(java_home, "/jre/lib/"JAVA_ARCH"/server/libjvm.so");
306
307         /* Check if that libjvm.so exists. */
308
309         printf("java_home=%s\n", java_home);
310
311         if (access(java_home, F_OK) == 0) {
312                 /* Yes, we add /jre to java.home. */
313
314                 strcpy(java_home, env_java_home);
315                 strcat(java_home, "/jre");
316         }
317         else {
318                 /* No, java.home is at it is. */
319
320                 strcpy(java_home, env_java_home);
321         }
322
323         properties_add("java.home", java_home);
324         properties_add("sun.boot.library.path", classpath_libdir);
325
326 # else
327
328 #  error unknown classpath configuration
329
330 # endif
331
332 #elif defined(ENABLE_JAVAME_CLDC1_1)
333
334     properties_add("microedition.configuration", "CLDC-1.1");
335     properties_add("microedition.platform", "generic");
336     properties_add("microedition.encoding", "ISO8859_1");
337     properties_add("microedition.profiles", "");
338
339 #else
340
341 # error unknown Java configuration
342
343 #endif
344
345         /* everything's ok */
346
347         return true;
348 }
349
350
351 /* properties_add **************************************************************
352
353    Adds a property entry to the internal property list.  If there's
354    already an entry with the same key, replace it.
355
356 *******************************************************************************/
357
358 void properties_add(char *key, char *value)
359 {
360         list_properties_entry *pe;
361
362         /* search for the entry */
363
364         for (pe = list_first_unsynced(list_properties); pe != NULL;
365                  pe = list_next_unsynced(list_properties, pe)) {
366                 if (strcmp(pe->key, key) == 0) {
367                         /* entry was found, replace the value */
368
369                         pe->value = value;
370
371                         return;
372                 }
373         }
374
375         /* entry was not found, insert a new one */
376
377         pe = NEW(list_properties_entry);
378
379         pe->key   = key;
380         pe->value = value;
381
382         list_add_last_unsynced(list_properties, pe);
383 }
384
385
386 /* properties_get **************************************************************
387
388    Get a property entry from the internal property list.
389
390 *******************************************************************************/
391
392 char *properties_get(char *key)
393 {
394         list_properties_entry *pe;
395
396         for (pe = list_first_unsynced(list_properties); pe != NULL;
397                  pe = list_next_unsynced(list_properties, pe)) {
398                 if (strcmp(pe->key, key) == 0)
399                         return pe->value;
400         }
401
402         return NULL;
403 }
404
405
406 /* properties_system_add *******************************************************
407
408    Adds a given property to the Java system properties.
409
410 *******************************************************************************/
411
412 void properties_system_add(java_handle_t *p, char *key, char *value)
413 {
414         methodinfo    *m;
415         java_handle_t *k;
416         java_handle_t *v;
417
418         /* search for method to add properties */
419
420         m = class_resolveclassmethod(p->vftbl->class,
421                                                                  utf_put,
422                                                                  utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
423                                                                  NULL,
424                                                                  true);
425
426         if (m == NULL)
427                 return;
428
429         /* add to the Java system properties */
430
431         k = javastring_new_from_utf_string(key);
432         v = javastring_new_from_utf_string(value);
433
434         (void) vm_call_method(m, p, k, v);
435 }
436
437
438 /* properties_system_add_all ***************************************************
439
440    Adds all properties from the properties list to the Java system
441    properties.
442
443    ARGUMENTS:
444        p.... is actually a java_util_Properties structure
445
446 *******************************************************************************/
447
448 #if defined(ENABLE_JAVASE)
449 void properties_system_add_all(java_handle_t *p)
450 {
451         list_properties_entry *pe;
452         methodinfo            *m;
453         java_handle_t         *key;
454         java_handle_t         *value;
455
456         /* search for method to add properties */
457
458         m = class_resolveclassmethod(p->vftbl->class,
459                                                                  utf_put,
460                                                                  utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
461                                                                  NULL,
462                                                                  true);
463
464         if (m == NULL)
465                 return;
466
467         /* process all properties stored in the internal table */
468
469         for (pe = list_first(list_properties); pe != NULL;
470                  pe = list_next(list_properties, pe)) {
471                 /* add to the Java system properties */
472
473                 key   = javastring_new_from_utf_string(pe->key);
474                 value = javastring_new_from_utf_string(pe->value);
475
476                 (void) vm_call_method(m, (java_handle_t *) p, key, value);
477         }
478 }
479 #endif /* defined(ENABLE_JAVASE) */
480
481
482 /*
483  * These are local overrides for various environment variables in Emacs.
484  * Please do not remove this and leave it at the end of the file, where
485  * Emacs will automagically detect them.
486  * ---------------------------------------------------------------------
487  * Local variables:
488  * mode: c
489  * indent-tabs-mode: t
490  * c-basic-offset: 4
491  * tab-width: 4
492  * End:
493  */