]>
Commit | Line | Data |
---|---|---|
f536cd95 TT |
1 | // posix.cc -- Helper functions for POSIX-flavored OSs. |
2 | ||
e59a1e40 | 3 | /* Copyright (C) 2000, 2001, 2002, 2006 Free Software Foundation |
f536cd95 TT |
4 | |
5 | This file is part of libgcj. | |
6 | ||
7 | This software is copyrighted work licensed under the terms of the | |
8 | Libgcj License. Please consult the file "LIBGCJ_LICENSE" for | |
9 | details. */ | |
10 | ||
11 | #include <config.h> | |
12 | ||
13 | #include "posix.h" | |
14 | ||
455cd615 | 15 | #include <stdlib.h> |
f536cd95 | 16 | #include <errno.h> |
73272ce6 | 17 | #include <signal.h> |
690e3ffd | 18 | #include <stdio.h> |
f536cd95 | 19 | |
33792684 RM |
20 | #ifdef HAVE_DLFCN_H |
21 | #include <dlfcn.h> | |
22 | #endif | |
23 | ||
1eba9d1f | 24 | #include <jvm.h> |
33792684 | 25 | #include <java-stack.h> |
1eba9d1f TT |
26 | #include <java/lang/Thread.h> |
27 | #include <java/io/InterruptedIOException.h> | |
455cd615 | 28 | #include <java/util/Properties.h> |
1eba9d1f | 29 | |
f536cd95 TT |
30 | #if defined (ECOS) |
31 | extern "C" unsigned long long _clock (void); | |
32 | #endif | |
33 | ||
c068c638 AH |
34 | #if defined(HAVE_PROC_SELF_EXE) |
35 | static char exec_name[20]; | |
36 | // initialized in _Jv_platform_initialize() | |
37 | #endif | |
38 | ||
39 | const char *_Jv_ThisExecutable (void) | |
40 | { | |
41 | #if defined(DISABLE_MAIN_ARGS) | |
42 | return "[Embedded App]"; | |
43 | #elif defined(HAVE_PROC_SELF_EXE) | |
44 | return exec_name; | |
45 | // initialized in _Jv_platform_initialize() | |
46 | #else | |
c4519773 | 47 | return _Jv_GetSafeArg (0); |
c068c638 AH |
48 | #endif |
49 | } | |
50 | ||
f536cd95 | 51 | // gettimeofday implementation. |
8eeda6e0 AM |
52 | jlong |
53 | _Jv_platform_gettimeofday () | |
f536cd95 TT |
54 | { |
55 | #if defined (HAVE_GETTIMEOFDAY) | |
8eeda6e0 AM |
56 | timeval tv; |
57 | gettimeofday (&tv, NULL); | |
f1148658 | 58 | return (tv.tv_sec * 1000LL) + (tv.tv_usec / 1000LL); |
f536cd95 | 59 | #elif defined (HAVE_TIME) |
f1148658 | 60 | return time (NULL) * 1000LL; |
f536cd95 TT |
61 | #elif defined (HAVE_FTIME) |
62 | struct timeb t; | |
63 | ftime (&t); | |
f1148658 | 64 | return (t.time * 1000LL) + t.millitm; |
f536cd95 TT |
65 | #elif defined (ECOS) |
66 | // FIXME. | |
8eeda6e0 | 67 | return _clock(); |
f536cd95 TT |
68 | #else |
69 | // In the absence of any function, time remains forever fixed. | |
8eeda6e0 | 70 | return 23000; |
f536cd95 TT |
71 | #endif |
72 | } | |
73 | ||
e59a1e40 TT |
74 | jlong |
75 | _Jv_platform_nanotime () | |
76 | { | |
77 | #ifdef HAVE_CLOCK_GETTIME | |
78 | struct timespec now; | |
6b04402b | 79 | clockid_t id; |
bd4ca424 TT |
80 | #ifdef CLOCK_MONOTONIC |
81 | id = CLOCK_MONOTONIC; | |
82 | #elif defined (CLOCK_HIGHRES) | |
83 | id = CLOCK_HIGHRES; | |
84 | #else | |
85 | id = CLOCK_REALTIME; | |
86 | #endif | |
87 | if (clock_gettime (id, &now) == 0) | |
e59a1e40 TT |
88 | { |
89 | jlong result = (jlong) now.tv_sec; | |
06fcf754 | 90 | result = result * 1000000000LL + now.tv_nsec; |
e59a1e40 TT |
91 | return result; |
92 | } | |
93 | // clock_gettime failed, but we can fall through. | |
94 | #endif // HAVE_CLOCK_GETTIME | |
06fcf754 GK |
95 | #if defined (HAVE_GETTIMEOFDAY) |
96 | { | |
97 | timeval tv; | |
98 | gettimeofday (&tv, NULL); | |
99 | return (tv.tv_sec * 1000000000LL) + tv.tv_usec * 1000LL; | |
100 | } | |
101 | #else | |
102 | return _Jv_platform_gettimeofday () * 1000000LL; | |
103 | #endif | |
e59a1e40 TT |
104 | } |
105 | ||
73272ce6 TT |
106 | // Platform-specific VM initialization. |
107 | void | |
108 | _Jv_platform_initialize (void) | |
109 | { | |
110 | #if defined (HAVE_SIGACTION) | |
111 | // We only want this on POSIX systems. | |
112 | struct sigaction act; | |
113 | act.sa_handler = SIG_IGN; | |
114 | sigemptyset (&act.sa_mask); | |
115 | act.sa_flags = 0; | |
116 | sigaction (SIGPIPE, &act, NULL); | |
117 | #else | |
118 | signal (SIGPIPE, SIG_IGN); | |
119 | #endif | |
c068c638 AH |
120 | |
121 | #if defined (HAVE_PROC_SELF_EXE) | |
122 | // Compute our executable name | |
123 | sprintf (exec_name, "/proc/%d/exe", getpid ()); | |
124 | #endif | |
73272ce6 TT |
125 | } |
126 | ||
455cd615 AK |
127 | // Set platform-specific System properties. |
128 | void | |
129 | _Jv_platform_initProperties (java::util::Properties* newprops) | |
130 | { | |
131 | // A convenience define. | |
132 | #define SET(Prop,Val) \ | |
133 | newprops->put(JvNewStringLatin1 (Prop), JvNewStringLatin1 (Val)) | |
134 | ||
135 | SET ("file.separator", "/"); | |
136 | SET ("path.separator", ":"); | |
137 | SET ("line.separator", "\n"); | |
1349c688 | 138 | const char *tmpdir = ::getenv("TMPDIR"); |
455cd615 AK |
139 | if (! tmpdir) |
140 | tmpdir = "/tmp"; | |
141 | SET ("java.io.tmpdir", tmpdir); | |
b3502aa8 JJ |
142 | const char *zoneinfodir = ::getenv("TZDATA"); |
143 | if (! zoneinfodir) | |
144 | zoneinfodir = "/usr/share/zoneinfo"; | |
145 | SET ("gnu.java.util.zoneinfo.dir", zoneinfodir); | |
455cd615 AK |
146 | } |
147 | ||
7258310a TT |
148 | static inline void |
149 | internal_gettimeofday (struct timeval *result) | |
150 | { | |
151 | #if defined (HAVE_GETTIMEOFDAY) | |
152 | gettimeofday (result, NULL); | |
153 | #else | |
154 | jlong val = _Jv_platform_gettimeofday (); | |
155 | result->tv_sec = val / 1000; | |
156 | result->tv_usec = (val % 1000) * 1000; | |
157 | #endif /* HAVE_GETTIMEOFDAY */ | |
158 | } | |
159 | ||
f536cd95 TT |
160 | // A wrapper for select() which ignores EINTR. |
161 | int | |
162 | _Jv_select (int n, fd_set *readfds, fd_set *writefds, | |
163 | fd_set *exceptfds, struct timeval *timeout) | |
164 | { | |
165 | #ifdef HAVE_SELECT | |
166 | // If we have a timeout, compute the absolute ending time. | |
167 | struct timeval end, delay; | |
168 | if (timeout) | |
169 | { | |
7258310a | 170 | internal_gettimeofday (&end); |
f536cd95 TT |
171 | end.tv_usec += timeout->tv_usec; |
172 | if (end.tv_usec >= 1000000) | |
173 | { | |
174 | ++end.tv_sec; | |
175 | end.tv_usec -= 1000000; | |
176 | } | |
177 | end.tv_sec += timeout->tv_sec; | |
178 | delay = *timeout; | |
179 | } | |
180 | else | |
181 | { | |
182 | // Placate compiler. | |
183 | delay.tv_sec = delay.tv_usec = 0; | |
184 | } | |
185 | ||
186 | while (1) | |
187 | { | |
188 | int r = select (n, readfds, writefds, exceptfds, | |
189 | timeout ? &delay : NULL); | |
190 | if (r != -1 || errno != EINTR) | |
191 | return r; | |
192 | ||
1eba9d1f TT |
193 | // Here we know we got EINTR. |
194 | if (java::lang::Thread::interrupted ()) | |
195 | throw new java::io::InterruptedIOException (JvNewStringLatin1 ("select interrupted")); | |
196 | ||
f536cd95 TT |
197 | struct timeval after; |
198 | if (timeout) | |
199 | { | |
7258310a | 200 | internal_gettimeofday (&after); |
f536cd95 TT |
201 | // Now compute new timeout argument. |
202 | delay.tv_usec = end.tv_usec - after.tv_usec; | |
203 | delay.tv_sec = end.tv_sec - after.tv_sec; | |
204 | if (delay.tv_usec < 0) | |
205 | { | |
206 | --delay.tv_sec; | |
207 | delay.tv_usec += 1000000; | |
208 | } | |
209 | if (delay.tv_sec < 0) | |
210 | { | |
211 | // We assume that the user wants a valid select() call | |
212 | // more than precise timing. So if we get a series of | |
213 | // EINTR we just keep trying with delay 0 until we get a | |
214 | // valid result. | |
215 | delay.tv_sec = 0; | |
216 | } | |
217 | } | |
218 | } | |
219 | #else /* HAVE_SELECT */ | |
220 | return 0; | |
221 | #endif | |
222 | } | |
33792684 RM |
223 | |
224 | // Given an address, find the object that defines it and the nearest | |
225 | // defined symbol to that address. Returns 0 if no object defines this | |
226 | // address. | |
227 | int | |
d25f0ebc | 228 | _Jv_platform_dladdr (void *addr, _Jv_AddrInfo *info) |
33792684 RM |
229 | { |
230 | int ret_val = 0; | |
231 | ||
232 | #if defined (HAVE_DLFCN_H) && defined (HAVE_DLADDR) | |
233 | Dl_info addr_info; | |
234 | ret_val = dladdr (addr, &addr_info); | |
235 | if (ret_val != 0) | |
236 | { | |
237 | info->file_name = addr_info.dli_fname; | |
238 | info->base = addr_info.dli_fbase; | |
239 | info->sym_name = addr_info.dli_sname; | |
240 | info->sym_addr = addr_info.dli_saddr; | |
241 | } | |
242 | #else | |
243 | info->file_name = NULL; | |
244 | info->base = NULL; | |
245 | info->sym_name = NULL; | |
246 | info->sym_addr = NULL; | |
247 | #endif | |
248 | ||
249 | return ret_val; | |
250 | } |