* arm.h (ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP): Wrap in
[official-gcc.git] / libjava / win32.cc
blobabe768ae5bd25550b9944c2affe3a4c1a33bec13
1 // win32.cc - Helper functions for Microsoft-flavored OSs.
3 /* Copyright (C) 2002, 2003 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9 details. */
11 #include <config.h>
12 #include <platform.h>
13 #include <sys/timeb.h>
14 #include <stdlib.h>
16 #include <java/lang/ArithmeticException.h>
17 #include <java/lang/UnsupportedOperationException.h>
18 #include <java/io/IOException.h>
19 #include <java/net/SocketException.h>
20 #include <java/util/Properties.h>
22 static LONG CALLBACK
23 win32_exception_handler (LPEXCEPTION_POINTERS e)
25 if (e->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
26 _Jv_ThrowNullPointerException();
27 else if (e->ExceptionRecord->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
28 throw new java::lang::ArithmeticException;
29 else
30 return EXCEPTION_CONTINUE_SEARCH;
33 // Platform-specific executable name
34 static char exec_name[MAX_PATH];
35 // initialized in _Jv_platform_initialize()
37 const char *_Jv_ThisExecutable (void)
39 return exec_name;
42 // Helper classes and methods implementation
44 // class WSAEventWrapper
45 WSAEventWrapper::WSAEventWrapper (int fd, DWORD dwSelFlags):
46 m_hEvent(0),
47 m_fd(fd),
48 m_dwSelFlags(dwSelFlags)
50 m_hEvent = WSACreateEvent ();
51 if (dwSelFlags)
52 WSAEventSelect(fd, m_hEvent, dwSelFlags);
55 WSAEventWrapper::~WSAEventWrapper ()
57 if (m_dwSelFlags)
59 WSAEventSelect(m_fd, m_hEvent, 0);
60 if (m_dwSelFlags & (FD_ACCEPT | FD_CONNECT))
62 // Set the socket back to non-blocking mode.
63 // Ignore any error since we're in a destructor.
64 unsigned long lSockOpt = 0L;
65 // blocking mode
66 ::ioctlsocket (m_fd, FIONBIO, &lSockOpt);
69 WSACloseEvent (m_hEvent);
72 // Error string text.
73 jstring
74 _Jv_WinStrError (LPCTSTR lpszPrologue, int nErrorCode)
76 LPTSTR lpMsgBuf = 0;
78 DWORD dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
79 FORMAT_MESSAGE_FROM_SYSTEM |
80 FORMAT_MESSAGE_IGNORE_INSERTS;
82 FormatMessage (dwFlags,
83 NULL,
84 (DWORD) nErrorCode,
85 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
86 (LPTSTR) &lpMsgBuf,
88 NULL);
90 jstring ret;
91 if (lpszPrologue)
93 LPTSTR lpszTemp =
94 (LPTSTR) _Jv_Malloc (strlen (lpszPrologue) +
95 strlen (lpMsgBuf) + 3);
96 strcpy (lpszTemp, lpszPrologue);
97 strcat (lpszTemp, ": ");
98 strcat (lpszTemp, lpMsgBuf);
99 ret = JvNewStringLatin1 (lpszTemp);
101 else
103 ret = JvNewStringLatin1 (lpMsgBuf);
106 LocalFree(lpMsgBuf);
107 return ret;
110 jstring
111 _Jv_WinStrError (int nErrorCode)
113 return _Jv_WinStrError (0, nErrorCode);
116 void _Jv_ThrowIOException (DWORD dwErrorCode)
118 throw new java::io::IOException (_Jv_WinStrError (dwErrorCode));
121 void _Jv_ThrowIOException()
123 DWORD dwErrorCode = WSAGetLastError ();
124 _Jv_ThrowIOException (dwErrorCode);
127 void _Jv_ThrowSocketException (DWORD dwErrorCode)
129 throw new java::net::SocketException (_Jv_WinStrError (dwErrorCode));
132 void _Jv_ThrowSocketException()
134 DWORD dwErrorCode = WSAGetLastError ();
135 _Jv_ThrowSocketException (dwErrorCode);
138 // Platform-specific VM initialization.
139 void
140 _Jv_platform_initialize (void)
142 // Initialise winsock for networking
143 WSADATA data;
144 if (WSAStartup (MAKEWORD (1, 1), &data))
145 MessageBox (NULL, "Error initialising winsock library.", "Error",
146 MB_OK | MB_ICONEXCLAMATION);
148 // Install exception handler
149 SetUnhandledExceptionFilter (win32_exception_handler);
151 // Initialize our executable name
152 GetModuleFileName(NULL, exec_name, sizeof(exec_name));
155 // gettimeofday implementation.
156 jlong
157 _Jv_platform_gettimeofday ()
159 struct timeb t;
160 ftime (&t);
161 return t.time * 1000LL + t.millitm;
164 // The following definitions "fake out" mingw to think that -mthreads
165 // was enabled and that mingwthr.dll was linked. GCJ-compiled
166 // applications don't need this helper library because we can safely
167 // detect thread death (return from Thread.run()).
169 int _CRT_MT = 1;
171 extern "C" int
172 __mingwthr_key_dtor (DWORD, void (*) (void *))
174 // FIXME: for now we do nothing; this causes a memory leak of
175 // approximately 24 bytes per thread created.
176 return 0;
179 // Set platform-specific System properties.
180 void
181 _Jv_platform_initProperties (java::util::Properties* newprops)
183 // A convenience define.
184 #define SET(Prop,Val) \
185 newprops->put(JvNewStringLatin1 (Prop), JvNewStringLatin1 (Val))
187 SET ("file.separator", "\\");
188 SET ("path.separator", ";");
189 SET ("line.separator", "\r\n");
191 // Use GetCurrentDirectory to set 'user.dir'.
192 DWORD buflen = MAX_PATH;
193 char *buffer = (char *) _Jv_MallocUnchecked (buflen);
194 if (buffer != NULL)
196 if (GetCurrentDirectory (buflen, buffer))
197 SET ("user.dir", buffer);
199 if (GetTempPath (buflen, buffer))
200 SET ("java.io.tmpdir", buffer);
202 _Jv_Free (buffer);
205 // Use GetUserName to set 'user.name'.
206 buflen = 257; // UNLEN + 1
207 buffer = (char *) _Jv_MallocUnchecked (buflen);
208 if (buffer != NULL)
210 if (GetUserName (buffer, &buflen))
211 SET ("user.name", buffer);
212 _Jv_Free (buffer);
215 // According to the api documentation for 'GetWindowsDirectory()', the
216 // environmental variable HOMEPATH always specifies the user's home
217 // directory or a default directory. On the 3 windows machines I checked
218 // only 1 had it set. If it's not set, JDK1.3.1 seems to set it to
219 // the windows directory, so we'll do the same.
220 char *userHome = NULL;
221 if ((userHome = ::getenv ("HOMEPATH")) == NULL )
223 // Check HOME since it's what I use.
224 if ((userHome = ::getenv ("HOME")) == NULL )
226 // Not found - use the windows directory like JDK1.3.1 does.
227 char *winHome = (char *) _Jv_MallocUnchecked (MAX_PATH);
228 if (winHome != NULL)
230 if (GetWindowsDirectory (winHome, MAX_PATH))
231 SET ("user.home", winHome);
232 _Jv_Free (winHome);
236 if (userHome != NULL)
237 SET ("user.home", userHome);
239 // Get and set some OS info.
240 OSVERSIONINFO osvi;
241 ZeroMemory (&osvi, sizeof(OSVERSIONINFO));
242 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
243 if (GetVersionEx (&osvi))
245 char *buffer = (char *) _Jv_MallocUnchecked (30);
246 if (buffer != NULL)
248 sprintf (buffer, "%d.%d", (int) osvi.dwMajorVersion,
249 (int) osvi.dwMinorVersion);
250 SET ("os.version", buffer);
251 _Jv_Free (buffer);
254 switch (osvi.dwPlatformId)
256 case VER_PLATFORM_WIN32_WINDOWS:
257 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
258 SET ("os.name", "Windows 95");
259 else if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
260 SET ("os.name", "Windows 98");
261 else if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
262 SET ("os.name", "Windows Me");
263 else
264 SET ("os.name", "Windows ??");
265 break;
267 case VER_PLATFORM_WIN32_NT:
268 if (osvi.dwMajorVersion <= 4 )
269 SET ("os.name", "Windows NT");
270 else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
271 SET ("os.name", "Windows 2000");
272 else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
273 SET ("os.name", "Windows XP");
274 else
275 SET ("os.name", "Windows NT ??");
276 break;
278 default:
279 SET ("os.name", "Windows UNKNOWN");
280 break;
284 // Set the OS architecture.
285 SYSTEM_INFO si;
286 GetSystemInfo (&si);
287 switch (si.wProcessorArchitecture)
289 case PROCESSOR_ARCHITECTURE_INTEL:
290 SET ("os.arch", "x86");
291 break;
292 case PROCESSOR_ARCHITECTURE_MIPS:
293 SET ("os.arch", "mips");
294 break;
295 case PROCESSOR_ARCHITECTURE_ALPHA:
296 SET ("os.arch", "alpha");
297 break;
298 case PROCESSOR_ARCHITECTURE_PPC:
299 SET ("os.arch", "ppc");
300 break;
301 case PROCESSOR_ARCHITECTURE_IA64:
302 SET ("os.arch", "ia64");
303 break;
304 case PROCESSOR_ARCHITECTURE_UNKNOWN:
305 default:
306 SET ("os.arch", "unknown");
307 break;
311 /* Store up to SIZE return address of the current program state in
312 ARRAY and return the exact number of values stored. */
314 backtrace (void **__array, int __size)
316 register void *_ebp __asm__ ("ebp");
317 register void *_esp __asm__ ("esp");
318 unsigned int *rfp;
320 int i=0;
321 for (rfp = *(unsigned int**)_ebp;
322 rfp && i < __size;
323 rfp = *(unsigned int **)rfp)
325 int diff = *rfp - (unsigned int)rfp;
326 if ((void*)rfp < _esp || diff > 4 * 1024 || diff < 0) break;
328 __array[i++] = (void*)(rfp[1]-4);
330 return i;
334 _Jv_select (int n, fd_set *readfds, fd_set *writefds,
335 fd_set *exceptfds, struct timeval *timeout)
337 int r = ::select (n, readfds, writefds, exceptfds, timeout);
338 if (r == SOCKET_ERROR)
340 DWORD dwErrorCode = WSAGetLastError ();
341 throw new java::io::IOException (_Jv_WinStrError (dwErrorCode));
343 return r;