Line data Source code
1 : /* src/cacao/cacao.cpp - contains main() of cacao
2 :
3 : Copyright (C) 1996-2005, 2006, 2007, 2008
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License as
10 : published by the Free Software Foundation; either version 2, or (at
11 : your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 :
26 : #include "config.h"
27 :
28 : #if defined(ENABLE_JRE_LAYOUT)
29 : # include <errno.h>
30 : # include <libgen.h>
31 : # include <unistd.h>
32 : #endif
33 :
34 : #include <stdint.h>
35 : #include <stdlib.h>
36 : #include <string.h>
37 :
38 : #include "native/jni.hpp"
39 : #include "native/native.hpp"
40 :
41 : #include "vm/os.hpp"
42 : #include "vm/vm.hpp"
43 :
44 :
45 : /* Defines. *******************************************************************/
46 :
47 : #define LIBJVM_NAME NATIVE_LIBRARY_PREFIX"jvm"NATIVE_LIBRARY_SUFFIX
48 :
49 :
50 : /* forward declarations *******************************************************/
51 :
52 : static JavaVMInitArgs* prepare_options(int argc, char** argv);
53 :
54 :
55 : /* main ************************************************************************
56 :
57 : The main program.
58 :
59 : *******************************************************************************/
60 :
61 165 : int main(int argc, char **argv)
62 : {
63 : #if defined(ENABLE_LIBJVM)
64 : char* path;
65 :
66 : # if defined(ENABLE_JRE_LAYOUT)
67 : int len;
68 : # endif
69 : #endif
70 :
71 : #if defined(ENABLE_LIBJVM)
72 : /* Variables for JNI_CreateJavaVM dlopen call. */
73 : void* libjvm_handle;
74 : void* libjvm_VM_create;
75 : void* libjvm_vm_run;
76 : const char* lterror;
77 :
78 : bool (*VM_create)(JavaVM**, void**, void*);
79 : void (*vm_run)(JavaVM*, JavaVMInitArgs*);
80 : #endif
81 :
82 : // Prepare the options.
83 165 : JavaVMInitArgs* vm_args = prepare_options(argc, argv);
84 :
85 : /* load and initialize a Java VM, return a JNI interface pointer in env */
86 :
87 : #if defined(ENABLE_LIBJVM)
88 : # if defined(ENABLE_JRE_LAYOUT)
89 : /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
90 :
91 : path = (char*) os::malloc(sizeof(char) * 4096);
92 :
93 : if (readlink("/proc/self/exe", path, 4095) == -1) {
94 : fprintf(stderr, "main: readlink failed: %s\n", strerror(errno));
95 : os::abort();
96 : }
97 :
98 : /* get the path of the current executable */
99 :
100 : path = os::dirname(path);
101 : len = os::strlen(path) + os::strlen("/../lib/"LIBJVM_NAME) + os::strlen("0");
102 :
103 : if (len > 4096) {
104 : fprintf(stderr, "main: libjvm name to long for buffer\n");
105 : os::abort();
106 : }
107 :
108 : /* concatenate the library name */
109 :
110 : strcat(path, "/../lib/"LIBJVM_NAME);
111 : # else
112 165 : path = (char*) CACAO_LIBDIR"/"LIBJVM_NAME;
113 : # endif
114 :
115 : /* First try to open where dlopen searches, e.g. LD_LIBRARY_PATH.
116 : If not found, try the absolute path. */
117 :
118 165 : libjvm_handle = os::dlopen(LIBJVM_NAME, RTLD_NOW);
119 :
120 165 : if (libjvm_handle == NULL) {
121 : /* save the error message */
122 :
123 0 : lterror = strdup(os::dlerror());
124 :
125 0 : libjvm_handle = os::dlopen(path, RTLD_NOW);
126 :
127 0 : if (libjvm_handle == NULL) {
128 : /* print the first error message too */
129 :
130 0 : fprintf(stderr, "main: os::dlopen failed: %s\n", lterror);
131 :
132 : /* and now the current one */
133 :
134 0 : fprintf(stderr, "main: os::dlopen failed: %s\n", os::dlerror());
135 0 : os::abort();
136 : }
137 :
138 : // Free the error string.
139 0 : os::free((void*) lterror);
140 : }
141 :
142 165 : libjvm_VM_create = os::dlsym(libjvm_handle, "VM_create");
143 :
144 165 : if (libjvm_VM_create == NULL) {
145 0 : fprintf(stderr, "main: lt_dlsym failed: %s\n", os::dlerror());
146 0 : os::abort();
147 : }
148 :
149 165 : VM_create = (bool (*)(JavaVM**, void**, void*)) (uintptr_t) libjvm_VM_create;
150 : #endif
151 :
152 : // Create the Java VM.
153 : JavaVM* vm;
154 : void* env; // We use a void* instead of a JNIEnv* here to prevent a compiler warning.
155 :
156 165 : (void) VM_create(&vm, &env, vm_args);
157 :
158 : #if defined(ENABLE_LIBJVM)
159 163 : libjvm_vm_run = os::dlsym(libjvm_handle, "vm_run");
160 :
161 163 : if (libjvm_vm_run == NULL) {
162 0 : fprintf(stderr, "main: os::dlsym failed: %s\n", os::dlerror());
163 0 : os::abort();
164 : }
165 :
166 163 : vm_run = (void (*)(JavaVM*, JavaVMInitArgs*)) (uintptr_t) libjvm_vm_run;
167 : #endif
168 :
169 : // Run the VM.
170 163 : vm_run(vm, vm_args);
171 :
172 : // Keep compiler happy.
173 0 : return 0;
174 : }
175 :
176 :
177 : /**
178 : * Prepare the JavaVMInitArgs structure.
179 : */
180 165 : static JavaVMInitArgs* prepare_options(int argc, char** argv)
181 : {
182 : JavaVMInitArgs* vm_args;
183 :
184 165 : vm_args = (JavaVMInitArgs*) malloc(sizeof(JavaVMInitArgs));
185 :
186 165 : vm_args->version = JNI_VERSION_1_2;
187 165 : vm_args->nOptions = argc - 1;
188 165 : vm_args->options = (JavaVMOption*) malloc(sizeof(JavaVMOption) * argc);
189 165 : vm_args->ignoreUnrecognized = JNI_FALSE;
190 :
191 647 : for (int i = 1; i < argc; i++)
192 482 : vm_args->options[i - 1].optionString = argv[i];
193 :
194 165 : return vm_args;
195 : }
196 :
197 :
198 : /*
199 : * These are local overrides for various environment variables in Emacs.
200 : * Please do not remove this and leave it at the end of the file, where
201 : * Emacs will automagically detect them.
202 : * ---------------------------------------------------------------------
203 : * Local variables:
204 : * mode: c++
205 : * indent-tabs-mode: t
206 : * c-basic-offset: 4
207 : * tab-width: 4
208 : * End:
209 : */
|