win32.cc: fixed tab...

* win32.cc: fixed tab, indentation and whitespace
	inconsistencies
	removed jvm.h include
	added includes java/lang/UnsupportedOperationException.h,
	java/io/IOException.h, java/net/SocketException.h
	(WSAEventWrapper): class implementation
	(_Jv_WinStrError): implemented both overloads
	(_Jv_ThrowIOException): implemented both overloads
	(_Jv_ThrowSocketException): implemented both overloads
	(_Jv_select): implemented
	* include/win32.h: fixed tab, indentation and whitespace
	inconsistencies
	wrapped <windows.h> include with  #define WIN32_LEAN_AND_MEAN
	added jvm.h include
	(WSAEventWrapper): added class declaration
	(_Jv_WinStrError): added both overload declarations
	(_Jv_ThrowIOException): added both overload declarations
	(_Jv_ThrowSocketException): added both overload declarations
	removed ENOTCONN, ECONNRESET and ENOPROTOOPT defines
	(_Jv_select): added declaration
	(_Jv_socket): removed
	(_Jv_connect): removed
	(_Jv_close): removed
	(_Jv_bind): removed
	(_Jv_accept): removed
	(_Jv_listen): removed
	(_Jv_write): removed
	(_Jv_read): removed
	* java/io/natFileDescriptorWin32.cc: fixed tab, indentation and
	whitespace inconsistencies
	replaced <windows.h> #include with <platform.h>
	removed jvm.h include
	(testCanUseGetHandleInfo): new function which tests whether Win32
	GetHandleInformation() call can be used with console buffer handles
	(only supported on >=WinNT 5.0)
	(winerr): removed (superseded by _Jv_WinStrError in include/win32.h)
	(valid): rewrote implementation using GetHandleInformation()
	(sync): 	changed exception throwing to use error string and exception
	helper methods declared in include/win32.h
	(open): likewise
	(write): likewise
	(setLength): likewise
	(close): likewise
	(seek): likewise
	(getFilePointer): likewise
	(read): likewise
	* java/io/natFileWin32.cc: fixed tab, indentation and
	whitespace inconsistencies
	replaced <windows.h> #include with <platform.h>
	removed jvm.h include
	(_access): use JV_TEMP_UTF_STRING
	(_stat): likewise
	(performMkDir): use JV_TEMP_UTF_STRING
	(performRenameTo): likewise
	(performDelete): likewise
	(performCreate): likewise
	(performSetReadOnly): likewise
	(performSetLastModified): likewise
	* java/lang/natWin32Process.cc: fixed tab, indentation and
	whitespace inconsistencies
	replaced <windows.h> #include with <platform.h>
	removed includes gcj/cni.h, jvm.h
	(new_string): removed
	(startProcess): use JV_TEMP_UTF_STRING,
	changed exception throwing to use error string and exception
	helper methods declared in include/win32.h
	* java/net/natInetAddressWin32.cc: fixed tab, indentation and
	whitespace inconsistencies
	replaced <windows.h> #include with <platform.h>
	removed jvm.h include
	removed DISABLE_JAVA_NET conditional code
	removed POSIX conditional code not relevant to Win32
	(aton): use JV_TEMP_UTF_STRING
	removed POSIX conditional code not relevant to Win32
	(lookup): likewise
	(getLocalHostName): likewise
	* java/net/natNetworkInterfaceWin32.cc: fixed tab, indentation and
	whitespace inconsistencies
	removed unnecessary windows.h, winsock.h and gcj/cni.h includes
	removed DISABLE_JAVA_NET conditional code
	removed POSIX conditional code not relevant to Win32
	(winsock2GetRealNetworkInterfaces): new function to compute network
	interfaces via Winsock2 API
	(determineGetRealNetworkInterfacesFN): new function for returning
	a function pointer to the function used to compute network interfaces.
	(getRealNetworkInterfaces): implemented
	* java/net/natPlainDatagramSocketImplWin32.cc: fixed tab, indentation and
	whitespace inconsistencies
	removed gcj/cni.h include
	removed DISABLE_JAVA_NET conditional code
	removed POSIX conditional code not relevant to Win32
	changed net POSIXisms to Win32isms
	replaced _Jv socket-related calls with their real Win32 equivalents
	changed exception throwing to use error string and exception
	helper methods declared in include/win32.h
	(peekData): implemented timeout support
	(receive): likewise
	* java/net/natPlainSocketImplWin32.cc: fixed tab, indentation and
	whitespace inconsistencies
	removed gcj/cni.h and gcj/javaprims.h includes
	removed DISABLE_JAVA_NET conditional code
	removed POSIX conditional code not relevant to Win32
	changed net POSIXisms to Win32isms
	replaced _Jv socket-related calls with their real Win32
	equivalents
	changed exception throwing to use error string and exception
	helper methods declared in include/win32.h
	(throwConnectException): helper function for connect()
	(connect): implemented timeout support
	(accept): likewise
	(doRead): new helper function common to both read() method overloads,
	includes timeout support
	(read): implemented both overloads in terms of doRead()
	(available): implemented using ioctlsocket()

From-SVN: r70904
This commit is contained in:
Mohan Embar 2003-08-29 04:21:01 +00:00 committed by Mohan Embar
parent a1d6cdc2d7
commit 5c14415811
10 changed files with 974 additions and 1409 deletions

View File

@ -1,3 +1,120 @@
2003-08-28 Mohan Embar <gnustuff@thisiscool.com>
* win32.cc: fixed tab, indentation and whitespace
inconsistencies
removed jvm.h include
added includes java/lang/UnsupportedOperationException.h,
java/io/IOException.h, java/net/SocketException.h
(WSAEventWrapper): class implementation
(_Jv_WinStrError): implemented both overloads
(_Jv_ThrowIOException): implemented both overloads
(_Jv_ThrowSocketException): implemented both overloads
(_Jv_select): implemented
* include/win32.h: fixed tab, indentation and whitespace
inconsistencies
wrapped <windows.h> include with #define WIN32_LEAN_AND_MEAN
added jvm.h include
(WSAEventWrapper): added class declaration
(_Jv_WinStrError): added both overload declarations
(_Jv_ThrowIOException): added both overload declarations
(_Jv_ThrowSocketException): added both overload declarations
removed ENOTCONN, ECONNRESET and ENOPROTOOPT defines
(_Jv_select): added declaration
(_Jv_socket): removed
(_Jv_connect): removed
(_Jv_close): removed
(_Jv_bind): removed
(_Jv_accept): removed
(_Jv_listen): removed
(_Jv_write): removed
(_Jv_read): removed
* java/io/natFileDescriptorWin32.cc: fixed tab, indentation and
whitespace inconsistencies
replaced <windows.h> #include with <platform.h>
removed jvm.h include
(testCanUseGetHandleInfo): new function which tests whether Win32
GetHandleInformation() call can be used with console buffer handles
(only supported on >=WinNT 5.0)
(winerr): removed (superseded by _Jv_WinStrError in include/win32.h)
(valid): rewrote implementation using GetHandleInformation()
(sync): changed exception throwing to use error string and exception
helper methods declared in include/win32.h
(open): likewise
(write): likewise
(setLength): likewise
(close): likewise
(seek): likewise
(getFilePointer): likewise
(read): likewise
* java/io/natFileWin32.cc: fixed tab, indentation and
whitespace inconsistencies
replaced <windows.h> #include with <platform.h>
removed jvm.h include
(_access): use JV_TEMP_UTF_STRING
(_stat): likewise
(performMkDir): use JV_TEMP_UTF_STRING
(performRenameTo): likewise
(performDelete): likewise
(performCreate): likewise
(performSetReadOnly): likewise
(performSetLastModified): likewise
* java/lang/natWin32Process.cc: fixed tab, indentation and
whitespace inconsistencies
replaced <windows.h> #include with <platform.h>
removed includes gcj/cni.h, jvm.h
(new_string): removed
(startProcess): use JV_TEMP_UTF_STRING,
changed exception throwing to use error string and exception
helper methods declared in include/win32.h
* java/net/natInetAddressWin32.cc: fixed tab, indentation and
whitespace inconsistencies
replaced <windows.h> #include with <platform.h>
removed jvm.h include
removed DISABLE_JAVA_NET conditional code
removed POSIX conditional code not relevant to Win32
(aton): use JV_TEMP_UTF_STRING
removed POSIX conditional code not relevant to Win32
(lookup): likewise
(getLocalHostName): likewise
* java/net/natNetworkInterfaceWin32.cc: fixed tab, indentation and
whitespace inconsistencies
removed unnecessary windows.h, winsock.h and gcj/cni.h includes
removed DISABLE_JAVA_NET conditional code
removed POSIX conditional code not relevant to Win32
(winsock2GetRealNetworkInterfaces): new function to compute network
interfaces via Winsock2 API
(determineGetRealNetworkInterfacesFN): new function for returning
a function pointer to the function used to compute network interfaces.
(getRealNetworkInterfaces): implemented
* java/net/natPlainDatagramSocketImplWin32.cc: fixed tab, indentation and
whitespace inconsistencies
removed gcj/cni.h include
removed DISABLE_JAVA_NET conditional code
removed POSIX conditional code not relevant to Win32
changed net POSIXisms to Win32isms
replaced _Jv socket-related calls with their real Win32 equivalents
changed exception throwing to use error string and exception
helper methods declared in include/win32.h
(peekData): implemented timeout support
(receive): likewise
* java/net/natPlainSocketImplWin32.cc: fixed tab, indentation and
whitespace inconsistencies
removed gcj/cni.h and gcj/javaprims.h includes
removed DISABLE_JAVA_NET conditional code
removed POSIX conditional code not relevant to Win32
changed net POSIXisms to Win32isms
replaced _Jv socket-related calls with their real Win32
equivalents
changed exception throwing to use error string and exception
helper methods declared in include/win32.h
(throwConnectException): helper function for connect()
(connect): implemented timeout support
(accept): likewise
(doRead): new helper function common to both read() method overloads,
includes timeout support
(read): implemented both overloads in terms of doRead()
(available): implemented using ioctlsocket()
2003-08-28 Mohan Embar <gnustuff@thisiscool.com> 2003-08-28 Mohan Embar <gnustuff@thisiscool.com>
* java/net/natInetAddressWin32.cc, * java/net/natInetAddressWin32.cc,

View File

@ -11,11 +11,14 @@ details. */
#ifndef __JV_WIN32_H__ #ifndef __JV_WIN32_H__
#define __JV_WIN32_H__ #define __JV_WIN32_H__
#define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#undef STRICT #undef STRICT
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <gcj/cni.h> #include <gcj/cni.h>
#include <jvm.h>
#include <java/util/Properties.h> #include <java/util/Properties.h>
#include <io.h> #include <io.h>
@ -40,21 +43,58 @@ details. */
// with the JNICALL definition in jni.h // with the JNICALL definition in jni.h
#define _Jv_platform_ffi_abi FFI_STDCALL #define _Jv_platform_ffi_abi FFI_STDCALL
#ifndef DISABLE_JAVA_NET /* Useful helper classes and methods. */
// these errors cannot occur on Win32 /* A C++ wrapper around a WSAEVENT which closes the event
#define ENOTCONN 0 in its destructor. If dwSelFlags is non-zero, we also
#define ECONNRESET 0 issue an WSAEventSelect on the socket descriptor with
the given flags; this is undone by a corresponding call
to WSAEventSelect(fd, 0, 0) in our destructor. */
class WSAEventWrapper
{
public:
WSAEventWrapper(int fd, DWORD dwSelFlags);
~WSAEventWrapper();
#ifndef ENOPROTOOPT WSAEVENT getEventHandle()
#define ENOPROTOOPT 109 {
#endif return m_hEvent;
}
#endif // DISABLE_JAVA_NET private:
WSAEVENT m_hEvent;
int m_fd;
DWORD m_dwSelFlags;
};
// Error string text. The int argument is compatible
// with both int WSAGetLastError() and DWORD GetLastError()
// I tried avoiding having to pass the error explicitly, but
// it didn't work this was invoked with say
// throw new SomeException(_Jv_WinStrError()).
extern jstring
_Jv_WinStrError (LPCTSTR lpszPrologue, int nErrorCode);
extern jstring
_Jv_WinStrError (int nErrorCode);
extern void
_Jv_ThrowIOException (DWORD dwErrorCode);
extern void
_Jv_ThrowIOException ();
extern void
_Jv_ThrowSocketException (DWORD dwErrorCode);
extern void
_Jv_ThrowSocketException ();
// Platform implementation
extern void _Jv_platform_initialize (void); extern void _Jv_platform_initialize (void);
extern void _Jv_platform_initProperties (java::util::Properties*); extern void _Jv_platform_initProperties (java::util::Properties*);
extern jlong _Jv_platform_gettimeofday (); extern jlong _Jv_platform_gettimeofday ();
extern int _Jv_select (int n, fd_set *, fd_set *, fd_set *, struct timeval *);
inline void inline void
_Jv_platform_close_on_exec (jint) _Jv_platform_close_on_exec (jint)
@ -77,58 +117,6 @@ _Jv_platform_usleep (unsigned long usecs)
} }
#endif /* JV_HASH_SYNCHRONIZATION */ #endif /* JV_HASH_SYNCHRONIZATION */
#ifndef DISABLE_JAVA_NET
static inline int
_Jv_socket (int domain, int type, int protocol)
{
return ::socket (domain, type, protocol);
}
inline int
_Jv_connect (jint fd, sockaddr *ptr, int len)
{
return ::connect (fd, ptr, len);
}
inline int
_Jv_close (jint fd)
{
return ::closesocket (fd);
}
inline int
_Jv_bind (int fd, struct sockaddr *addr, int addrlen)
{
return ::bind (fd, addr, addrlen);
}
inline int
_Jv_accept (int fd, struct sockaddr *addr, socklen_t *addrlen)
{
return ::accept (fd, addr, addrlen);
}
inline int
_Jv_listen (int fd, int backlog)
{
return ::listen (fd, backlog);
}
inline int
_Jv_write(int s, void *buf, int len)
{
return ::send (s, (char*) buf, len, 0);
}
inline int
_Jv_read(int s, void *buf, int len)
{
return ::recv (s, (char*) buf, len, 0);
}
#endif /* DISABLE_JAVA_NET */
/* Store up to SIZE return address of the current program state in /* Store up to SIZE return address of the current program state in
ARRAY and return the exact number of values stored. */ ARRAY and return the exact number of values stored. */
extern int backtrace (void **__array, int __size); extern int backtrace (void **__array, int __size);

View File

@ -13,15 +13,13 @@ details. */
// need to change to use the windows asynchronous IO functions // need to change to use the windows asynchronous IO functions
#include <config.h> #include <config.h>
#include <platform.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <windows.h>
#undef STRICT #undef STRICT
#include <gcj/cni.h>
#include <jvm.h>
#include <java/io/FileDescriptor.h> #include <java/io/FileDescriptor.h>
#include <java/io/SyncFailedException.h> #include <java/io/SyncFailedException.h>
#include <java/io/IOException.h> #include <java/io/IOException.h>
@ -33,6 +31,16 @@ details. */
#include <java/lang/Thread.h> #include <java/lang/Thread.h>
#include <java/io/FileNotFoundException.h> #include <java/io/FileNotFoundException.h>
static bool testCanUseGetHandleInfo()
{
/* Test to see whether GetHandleInformation can be used
for console input or screen buffers. This is better
a kludgy OS version check. */
DWORD dwFlags;
return GetHandleInformation (GetStdHandle (STD_INPUT_HANDLE),
&dwFlags) != 0;
}
// FIXME: casting a FILE (pointer) to a jint will not work on Win64 -- // FIXME: casting a FILE (pointer) to a jint will not work on Win64 --
// we should be using gnu.gcj.RawData's. // we should be using gnu.gcj.RawData's.
@ -44,41 +52,32 @@ java::io::FileDescriptor::init(void)
err = new java::io::FileDescriptor((jint)(GetStdHandle (STD_ERROR_HANDLE))); err = new java::io::FileDescriptor((jint)(GetStdHandle (STD_ERROR_HANDLE)));
} }
static char *
winerr (void)
{
static LPVOID last = NULL;
LPVOID old = NULL;
if (last)
old = last;
FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &last,
0,
NULL);
if (old)
LocalFree (old);
return (char *)last;
}
jboolean jboolean
java::io::FileDescriptor::valid (void) { java::io::FileDescriptor::valid (void) {
BY_HANDLE_FILE_INFORMATION info; static bool bCanUseGetHandleInfo = testCanUseGetHandleInfo();
return GetFileInformationByHandle ((HANDLE)fd, &info) != 0; if (bCanUseGetHandleInfo)
{
/* As with UNIX, a "file" descriptor can be one of
a gazillion possible underlying things like a pipe
or socket, so we can't get too fancy here. */
DWORD dwFlags;
HANDLE h = (HANDLE) fd;
return GetHandleInformation (h, &dwFlags) != 0;
}
else
{
/* Can't use GetHandleInformation() for console handles on < WinNT 5. */
return true;
}
} }
void void
java::io::FileDescriptor::sync (void) { java::io::FileDescriptor::sync (void) {
if (! FlushFileBuffers ((HANDLE)fd)) if (! FlushFileBuffers ((HANDLE)fd))
throw new SyncFailedException (JvNewStringLatin1 (winerr ())); {
DWORD dwErrorCode = GetLastError ();
throw new SyncFailedException (_Jv_WinStrError (dwErrorCode));
}
} }
jint jint
@ -87,10 +86,8 @@ java::io::FileDescriptor::open (jstring path, jint jflags) {
HANDLE handle = NULL; HANDLE handle = NULL;
DWORD access = 0; DWORD access = 0;
DWORD create = OPEN_EXISTING; DWORD create = OPEN_EXISTING;
char buf[MAX_PATH] = "";
JV_TEMP_UTF_STRING(cpath, path)
jsize total = JvGetStringUTFRegion(path, 0, path->length(), buf);
buf[total] = '\0';
JvAssert((jflags & READ) || (jflags & WRITE)); JvAssert((jflags & READ) || (jflags & WRITE));
@ -98,9 +95,9 @@ java::io::FileDescriptor::open (jstring path, jint jflags) {
{ {
access = GENERIC_READ | GENERIC_WRITE; access = GENERIC_READ | GENERIC_WRITE;
if (jflags & EXCL) if (jflags & EXCL)
create = CREATE_NEW; // this will raise error if file exists. create = CREATE_NEW; // this will raise error if file exists.
else else
create = OPEN_ALWAYS; // equivalent to O_CREAT create = OPEN_ALWAYS; // equivalent to O_CREAT
} }
else if (jflags & READ) else if (jflags & READ)
{ {
@ -111,20 +108,19 @@ java::io::FileDescriptor::open (jstring path, jint jflags) {
{ {
access = GENERIC_WRITE; access = GENERIC_WRITE;
if (jflags & EXCL) if (jflags & EXCL)
create = CREATE_NEW; create = CREATE_NEW;
else if (jflags & APPEND) else if (jflags & APPEND)
create = OPEN_ALWAYS; create = OPEN_ALWAYS;
else else
create = CREATE_ALWAYS; create = CREATE_ALWAYS;
} }
handle = CreateFile(buf, access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, create, 0, NULL); handle = CreateFile(cpath, access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, create, 0, NULL);
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
{ {
char msg[MAX_PATH + 1000]; DWORD dwErrorCode = GetLastError ();
sprintf (msg, "%s: %s", buf, winerr ()); throw new FileNotFoundException (_Jv_WinStrError (cpath, dwErrorCode));
throw new FileNotFoundException (JvNewStringLatin1 (msg));
} }
// For APPEND mode, move the file pointer to the end of the file. // For APPEND mode, move the file pointer to the end of the file.
@ -132,7 +128,10 @@ java::io::FileDescriptor::open (jstring path, jint jflags) {
{ {
DWORD low = SetFilePointer (handle, 0, NULL, FILE_END); DWORD low = SetFilePointer (handle, 0, NULL, FILE_END);
if ((low == 0xffffffff) && (GetLastError () != NO_ERROR)) if ((low == 0xffffffff) && (GetLastError () != NO_ERROR))
throw new FileNotFoundException (JvNewStringLatin1 (winerr ())); {
DWORD dwErrorCode = GetLastError ();
throw new FileNotFoundException (_Jv_WinStrError (cpath, dwErrorCode));
}
} }
return (jint)handle; return (jint)handle;
} }
@ -149,13 +148,13 @@ java::io::FileDescriptor::write (jint b)
{ {
InterruptedIOException *iioe = new InterruptedIOException (JvNewStringLatin1 ("write interrupted")); InterruptedIOException *iioe = new InterruptedIOException (JvNewStringLatin1 ("write interrupted"));
iioe->bytesTransferred = bytesWritten; iioe->bytesTransferred = bytesWritten;
throw iioe; throw iioe;
} }
if (bytesWritten != 1) if (bytesWritten != 1)
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
} }
else else
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
// FIXME: loop until bytesWritten == 1 // FIXME: loop until bytesWritten == 1
} }
@ -175,11 +174,11 @@ java::io::FileDescriptor::write(jbyteArray b, jint offset, jint len)
{ {
InterruptedIOException *iioe = new InterruptedIOException (JvNewStringLatin1 ("write interrupted")); InterruptedIOException *iioe = new InterruptedIOException (JvNewStringLatin1 ("write interrupted"));
iioe->bytesTransferred = bytesWritten; iioe->bytesTransferred = bytesWritten;
throw iioe; throw iioe;
} }
} }
else else
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
// FIXME: loop until bytesWritten == len // FIXME: loop until bytesWritten == len
} }
@ -189,7 +188,7 @@ java::io::FileDescriptor::close (void)
HANDLE save = (HANDLE)fd; HANDLE save = (HANDLE)fd;
fd = (jint)INVALID_HANDLE_VALUE; fd = (jint)INVALID_HANDLE_VALUE;
if (! CloseHandle (save)) if (! CloseHandle (save))
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
} }
void void
@ -201,46 +200,46 @@ java::io::FileDescriptor::setLength(jlong pos)
// Get the original file pointer. // Get the original file pointer.
if (SetFilePointer((HANDLE) fd, (LONG) 0, &liOrigFilePointer, if (SetFilePointer((HANDLE) fd, (LONG) 0, &liOrigFilePointer,
FILE_CURRENT) != (BOOL) 0 FILE_CURRENT) != (BOOL) 0
&& (GetLastError() != NO_ERROR)) && (GetLastError() != NO_ERROR))
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
// Get the length of the file. // Get the length of the file.
if (SetFilePointer((HANDLE) fd, (LONG) 0, &liEndFilePointer, if (SetFilePointer((HANDLE) fd, (LONG) 0, &liEndFilePointer,
FILE_END) != (BOOL) 0 FILE_END) != (BOOL) 0
&& (GetLastError() != NO_ERROR)) && (GetLastError() != NO_ERROR))
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
if ((jlong)liEndFilePointer == pos) if ((jlong)liEndFilePointer == pos)
{ {
// Restore the file pointer. // Restore the file pointer.
if (liOrigFilePointer != liEndFilePointer) if (liOrigFilePointer != liEndFilePointer)
{ {
if (SetFilePointer((HANDLE) fd, liOrigFilePointer, &liNewFilePointer, if (SetFilePointer((HANDLE) fd, liOrigFilePointer, &liNewFilePointer,
FILE_BEGIN) != (BOOL) 0 FILE_BEGIN) != (BOOL) 0
&& (GetLastError() != NO_ERROR)) && (GetLastError() != NO_ERROR))
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
} }
return; return;
} }
// Seek to the new end of file. // Seek to the new end of file.
if (SetFilePointer((HANDLE) fd, (LONG) pos, &liNewFilePointer, if (SetFilePointer((HANDLE) fd, (LONG) pos, &liNewFilePointer,
FILE_BEGIN) != (BOOL) 0 FILE_BEGIN) != (BOOL) 0
&& (GetLastError() != NO_ERROR)) && (GetLastError() != NO_ERROR))
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
// Truncate the file at this point. // Truncate the file at this point.
if (SetEndOfFile((HANDLE) fd) != (BOOL) 0 && (GetLastError() != NO_ERROR)) if (SetEndOfFile((HANDLE) fd) != (BOOL) 0 && (GetLastError() != NO_ERROR))
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
if (liOrigFilePointer < liNewFilePointer) if (liOrigFilePointer < liNewFilePointer)
{ {
// Restore the file pointer. // Restore the file pointer.
if (SetFilePointer((HANDLE) fd, liOrigFilePointer, &liNewFilePointer, if (SetFilePointer((HANDLE) fd, liOrigFilePointer, &liNewFilePointer,
FILE_BEGIN) != (BOOL) 0 FILE_BEGIN) != (BOOL) 0
&& (GetLastError() != NO_ERROR)) && (GetLastError() != NO_ERROR))
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
} }
} }
@ -262,7 +261,7 @@ java::io::FileDescriptor::seek (jlong pos, jint whence, jboolean eof_trunc)
LONG high = pos >> 32; LONG high = pos >> 32;
DWORD low = SetFilePointer ((HANDLE)fd, (DWORD)(0xffffffff & pos), &high, whence == SET ? FILE_BEGIN : FILE_CURRENT); DWORD low = SetFilePointer ((HANDLE)fd, (DWORD)(0xffffffff & pos), &high, whence == SET ? FILE_BEGIN : FILE_CURRENT);
if ((low == 0xffffffff) && (GetLastError () != NO_ERROR)) if ((low == 0xffffffff) && (GetLastError () != NO_ERROR))
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
return low; return low;
} }
@ -272,7 +271,7 @@ java::io::FileDescriptor::getFilePointer(void)
LONG high = 0; LONG high = 0;
DWORD low = SetFilePointer ((HANDLE)fd, 0, &high, FILE_CURRENT); DWORD low = SetFilePointer ((HANDLE)fd, 0, &high, FILE_CURRENT);
if ((low == 0xffffffff) && (GetLastError() != NO_ERROR)) if ((low == 0xffffffff) && (GetLastError() != NO_ERROR))
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
return (((jlong)high) << 32L) | (jlong)low; return (((jlong)high) << 32L) | (jlong)low;
} }
@ -298,7 +297,7 @@ java::io::FileDescriptor::read(void)
if (GetLastError () == ERROR_BROKEN_PIPE) if (GetLastError () == ERROR_BROKEN_PIPE)
return -1; return -1;
else else
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
} }
if (! read) if (! read)
@ -329,7 +328,7 @@ java::io::FileDescriptor::read(jbyteArray buffer, jint offset, jint count)
if (GetLastError () == ERROR_BROKEN_PIPE) if (GetLastError () == ERROR_BROKEN_PIPE)
return -1; return -1;
else else
throw new IOException (JvNewStringLatin1 (winerr ())); _Jv_ThrowIOException ();
} }
if (read == 0) return -1; if (read == 0) return -1;

View File

@ -9,15 +9,13 @@ Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */ details. */
#include <config.h> #include <config.h>
#include <platform.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <windows.h>
#undef STRICT #undef STRICT
#include <gcj/cni.h>
#include <jvm.h>
#include <java/io/File.h> #include <java/io/File.h>
#include <java/io/IOException.h> #include <java/io/IOException.h>
#include <java/util/Vector.h> #include <java/util/Vector.h>
@ -42,12 +40,9 @@ details. */
jboolean jboolean
java::io::File::_access (jint query) java::io::File::_access (jint query)
{ {
jstring canon = getCanonicalPath(); JV_TEMP_UTF_STRING (canon, getCanonicalPath());
if (! canon) if (!canon)
return false; return false;
char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (canon) + 1);
jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf);
buf[total] = '\0';
JvAssert (query == READ || query == WRITE || query == EXISTS); JvAssert (query == READ || query == WRITE || query == EXISTS);
@ -55,7 +50,7 @@ java::io::File::_access (jint query)
// If the file exists but cannot be read because of the secuirty attributes // If the file exists but cannot be read because of the secuirty attributes
// on an NTFS disk this wont work (it reports it can be read but cant) // on an NTFS disk this wont work (it reports it can be read but cant)
// Could we use something from the security API? // Could we use something from the security API?
DWORD attributes = GetFileAttributes (buf); DWORD attributes = GetFileAttributes (canon);
if ((query == EXISTS) || (query == READ)) if ((query == EXISTS) || (query == READ))
return (attributes == 0xffffffff) ? false : true; return (attributes == 0xffffffff) ? false : true;
else else
@ -65,16 +60,13 @@ java::io::File::_access (jint query)
jboolean jboolean
java::io::File::_stat (jint query) java::io::File::_stat (jint query)
{ {
jstring canon = getCanonicalPath(); JV_TEMP_UTF_STRING (canon, getCanonicalPath());
if (! canon) if (!canon)
return false; return false;
char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (canon) + 1);
jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf);
buf[total] = '\0';
JvAssert (query == DIRECTORY || query == ISFILE); JvAssert (query == DIRECTORY || query == ISFILE);
DWORD attributes = GetFileAttributes (buf); DWORD attributes = GetFileAttributes (canon);
if (attributes == 0xffffffff) if (attributes == 0xffffffff)
return false; return false;
@ -87,18 +79,15 @@ java::io::File::_stat (jint query)
jlong jlong
java::io::File::attr (jint query) java::io::File::attr (jint query)
{ {
jstring canon = getCanonicalPath(); JV_TEMP_UTF_STRING (canon, getCanonicalPath());
if (! canon) if (!canon)
return false; return false;
char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (canon) + 1);
jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf);
buf[total] = '\0';
JvAssert (query == MODIFIED || query == LENGTH); JvAssert (query == MODIFIED || query == LENGTH);
WIN32_FIND_DATA info; WIN32_FIND_DATA info;
HANDLE sHandle; HANDLE sHandle;
if ( ( sHandle = FindFirstFile( buf, &info)) == INVALID_HANDLE_VALUE) if ( ( sHandle = FindFirstFile( canon, &info)) == INVALID_HANDLE_VALUE)
return 0; return 0;
FindClose( sHandle); FindClose( sHandle);
@ -119,13 +108,11 @@ java::io::File::attr (jint query)
jstring jstring
java::io::File::getCanonicalPath (void) java::io::File::getCanonicalPath (void)
{ {
char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1); JV_TEMP_UTF_STRING (cpath, path);
jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
buf[total] = '\0';
LPTSTR unused; LPTSTR unused;
char buf2[MAX_PATH]; char buf2[MAX_PATH];
if(!GetFullPathName(buf, MAX_PATH, buf2, &unused)) if(!GetFullPathName(cpath, MAX_PATH, buf2, &unused))
throw new IOException (JvNewStringLatin1 ("GetFullPathName failed")); throw new IOException (JvNewStringLatin1 ("GetFullPathName failed"));
// FIXME: what encoding to assume for file names? This affects many // FIXME: what encoding to assume for file names? This affects many
@ -152,7 +139,7 @@ java::io::File::isAbsolute (void)
&& (path->charAt(0) < 'A' || path->charAt(0) > 'Z')) && (path->charAt(0) < 'A' || path->charAt(0) > 'Z'))
return false; return false;
return (path->charAt(1) == ':' return (path->charAt(1) == ':'
&& (path->charAt(2) == '/' || path->charAt(2) == '\\')); && (path->charAt(2) == '/' || path->charAt(2) == '\\'));
} }
void java::io::File::init_native () void java::io::File::init_native ()
@ -163,8 +150,8 @@ void java::io::File::init_native ()
jobjectArray jobjectArray
java::io::File::performList (java::io::FilenameFilter *filter, java::io::File::performList (java::io::FilenameFilter *filter,
java::io::FileFilter *fileFilter, java::io::FileFilter *fileFilter,
java::lang::Class *clazz) java::lang::Class *clazz)
{ {
jstring canon = getCanonicalPath(); jstring canon = getCanonicalPath();
if (! canon) if (! canon)
@ -190,16 +177,16 @@ java::io::File::performList (java::io::FilenameFilter *filter,
jstring name = JvNewStringUTF (data.cFileName); jstring name = JvNewStringUTF (data.cFileName);
if (filter && !filter->accept(this, name)) if (filter && !filter->accept(this, name))
continue; continue;
if (clazz == &java::io::File::class$) if (clazz == &java::io::File::class$)
{ {
java::io::File *file = new java::io::File (this, name); java::io::File *file = new java::io::File (this, name);
if (fileFilter && !fileFilter->accept(file)) if (fileFilter && !fileFilter->accept(file))
continue; continue;
vec->addElement (file); vec->addElement (file);
} }
else else
vec->addElement (name); vec->addElement (name);
} }
} }
while (FindNextFile (handle, &data)); while (FindNextFile (handle, &data));
@ -217,53 +204,42 @@ java::io::File::performList (java::io::FilenameFilter *filter,
jboolean jboolean
java::io::File::performMkdir (void) java::io::File::performMkdir (void)
{ {
char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1); JV_TEMP_UTF_STRING (cpath, path);
jsize total = JvGetStringUTFRegion(path, 0, path->length(), buf); return (CreateDirectory(cpath, NULL)) ? true : false;
buf[total] = '\0';
return (CreateDirectory(buf, NULL)) ? true : false;
} }
jboolean jboolean
java::io::File::performRenameTo (File *dest) java::io::File::performRenameTo (File *dest)
{ {
char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1); JV_TEMP_UTF_STRING (pathFrom, path);
jsize total = JvGetStringUTFRegion(path, 0, path->length(), buf); JV_TEMP_UTF_STRING (pathTo, dest->path);
buf[total] = '\0'; return (MoveFile(pathFrom, pathTo)) ? true : false;
char *buf2 = (char *) __builtin_alloca (JvGetStringUTFLength (dest->path)
+ 1);
total = JvGetStringUTFRegion(dest->path, 0, dest->path->length(), buf2);
buf2[total] = '\0';
return (MoveFile(buf, buf2)) ? true : false;
} }
jboolean jboolean
java::io::File::performDelete () java::io::File::performDelete ()
{ {
jstring canon = getCanonicalPath(); JV_TEMP_UTF_STRING (canon, getCanonicalPath());
char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (canon) + 1); if (!canon)
jsize total = JvGetStringUTFRegion(canon, 0, canon->length(), buf); return false;
buf[total] = '\0';
DWORD attributes = GetFileAttributes (buf); DWORD attributes = GetFileAttributes (canon);
if (attributes == 0xffffffff) if (attributes == 0xffffffff)
return false; return false;
if (attributes & FILE_ATTRIBUTE_DIRECTORY) if (attributes & FILE_ATTRIBUTE_DIRECTORY)
return (RemoveDirectory (buf)) ? true : false; return (RemoveDirectory (canon)) ? true : false;
else else
return (DeleteFile (buf)) ? true : false; return (DeleteFile (canon)) ? true : false;
} }
jboolean java::io::File::performCreate (void) jboolean java::io::File::performCreate (void)
{ {
jstring canon = getCanonicalPath (); JV_TEMP_UTF_STRING (canon, getCanonicalPath());
char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (canon) + 1); if (!canon)
jsize total = JvGetStringUTFRegion (canon, 0, canon->length (), buf); return false;
buf[total] = '\0';
HANDLE h = CreateFile (buf, 0, 0, NULL, CREATE_NEW, HANDLE h = CreateFile (canon, 0, 0, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL); FILE_ATTRIBUTE_NORMAL, NULL);
if (h != INVALID_HANDLE_VALUE) if (h != INVALID_HANDLE_VALUE)
{ {
@ -281,15 +257,14 @@ jboolean java::io::File::performCreate (void)
jboolean java::io::File::performSetReadOnly () jboolean java::io::File::performSetReadOnly ()
{ {
jstring canon = getCanonicalPath (); JV_TEMP_UTF_STRING (canon, getCanonicalPath());
char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (canon) + 1); if (!canon)
jsize total = JvGetStringUTFRegion (canon, 0, canon->length (), buf); return false;
buf[total] = '\0';
DWORD attrs = GetFileAttributes (buf); DWORD attrs = GetFileAttributes (canon);
if (attrs != INVALID_FILE_ATTRIBUTES) if (attrs != INVALID_FILE_ATTRIBUTES)
{ {
if (SetFileAttributes (buf, attrs | FILE_ATTRIBUTE_READONLY) != 0) if (SetFileAttributes (canon, attrs | FILE_ATTRIBUTE_READONLY) != 0)
return true; return true;
else else
return false; return false;
@ -300,10 +275,9 @@ jboolean java::io::File::performSetReadOnly ()
jboolean java::io::File::performSetLastModified (jlong time) jboolean java::io::File::performSetLastModified (jlong time)
{ {
jstring canon = getCanonicalPath (); JV_TEMP_UTF_STRING (canon, getCanonicalPath());
char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (canon) + 1); if (!canon)
jsize total = JvGetStringUTFRegion (canon, 0, canon->length (), buf); return false;
buf[total] = '\0';
FILETIME modTime; FILETIME modTime;
long long mTime100ns = ((long long) time /* Ha! */ long long mTime100ns = ((long long) time /* Ha! */
@ -313,7 +287,7 @@ jboolean java::io::File::performSetLastModified (jlong time)
modTime.dwHighDateTime = (DWORD) (mTime100ns >> 32); modTime.dwHighDateTime = (DWORD) (mTime100ns >> 32);
jboolean retVal = false; jboolean retVal = false;
HANDLE h = CreateFile (buf, FILE_WRITE_ATTRIBUTES, HANDLE h = CreateFile (canon, FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL); NULL, OPEN_EXISTING, 0, NULL);

View File

@ -9,18 +9,11 @@ Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */ details. */
#include <config.h> #include <config.h>
#include <platform.h>
#include <stdio.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// Conflicts with the definition in "java/lang/reflect/Modifier.h" // Conflicts with the definition in "java/lang/reflect/Modifier.h"
#undef STRICT #undef STRICT
#include <gcj/cni.h>
#include <jvm.h>
#include <java/lang/ConcreteProcess.h> #include <java/lang/ConcreteProcess.h>
#include <java/lang/IllegalThreadStateException.h> #include <java/lang/IllegalThreadStateException.h>
#include <java/lang/InterruptedException.h> #include <java/lang/InterruptedException.h>
@ -111,16 +104,6 @@ java::lang::ConcreteProcess::waitFor (void)
return exitCode; return exitCode;
} }
static char *
new_string (jstring string)
{
jsize s = _Jv_GetStringUTFLength (string);
char *buf = (char *) _Jv_Malloc (s + 1);
_Jv_GetStringUTFRegion (string, 0, s, buf);
buf[s] = '\0';
return buf;
}
void void
java::lang::ConcreteProcess::startProcess (jstringArray progarray, java::lang::ConcreteProcess::startProcess (jstringArray progarray,
jstringArray envp, jstringArray envp,
@ -177,9 +160,7 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray,
} }
// Get the working directory path, if specified. // Get the working directory path, if specified.
char *wdir = NULL; JV_TEMP_UTF_STRING (wdir, dir ? dir->getPath () : 0);
if (dir != NULL)
wdir = new_string (dir->getPath ());
errorStream = NULL; errorStream = NULL;
inputStream = NULL; inputStream = NULL;
@ -204,29 +185,25 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray,
sAttrs.lpSecurityDescriptor = NULL; sAttrs.lpSecurityDescriptor = NULL;
char tmpBuff[64];
if (CreatePipe (&cldStdInRd, &cldStdInWr, &sAttrs, 0) == 0) if (CreatePipe (&cldStdInRd, &cldStdInWr, &sAttrs, 0) == 0)
{ {
sprintf (tmpBuff, DWORD dwErrorCode = GetLastError ();
"Error creating stdin pipe (Win32 Error Code: %lu)", throw new IOException (_Jv_WinStrError ("Error creating stdin pipe",
GetLastError ()); dwErrorCode));
throw new IOException (JvNewStringLatin1 (tmpBuff));
} }
if (CreatePipe (&cldStdOutRd, &cldStdOutWr, &sAttrs, 0) == 0) if (CreatePipe (&cldStdOutRd, &cldStdOutWr, &sAttrs, 0) == 0)
{ {
sprintf (tmpBuff, DWORD dwErrorCode = GetLastError ();
"Error creating stdout pipe (Win32 Error Code: %lu)", throw new IOException (_Jv_WinStrError ("Error creating stdout pipe",
GetLastError ()); dwErrorCode));
throw new IOException (JvNewStringLatin1 (tmpBuff));
} }
if (CreatePipe (&cldStdErrRd, &cldStdErrWr, &sAttrs, 0) == 0) if (CreatePipe (&cldStdErrRd, &cldStdErrWr, &sAttrs, 0) == 0)
{ {
sprintf (tmpBuff, DWORD dwErrorCode = GetLastError ();
"Error creating stderr pipe (Win32 Error Code: %lu)", throw new IOException (_Jv_WinStrError ("Error creating stderr pipe",
GetLastError ()); dwErrorCode));
throw new IOException (JvNewStringLatin1 (tmpBuff));
} }
outputStream = new FileOutputStream outputStream = new FileOutputStream
@ -263,10 +240,9 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray,
&si, &si,
&pi) == 0) &pi) == 0)
{ {
sprintf (tmpBuff, DWORD dwErrorCode = GetLastError ();
"Error creating child process (Win32 Error Code: %lu)", throw new IOException (
GetLastError ()); _Jv_WinStrError ("Error creating child process", dwErrorCode));
throw new IOException (JvNewStringLatin1 (tmpBuff));
} }
procHandle = (jint ) pi.hProcess; procHandle = (jint ) pi.hProcess;
@ -279,8 +255,6 @@ java::lang::ConcreteProcess::startProcess (jstringArray progarray,
_Jv_Free (cmdLine); _Jv_Free (cmdLine);
if (env != NULL) if (env != NULL)
_Jv_Free (env); _Jv_Free (env);
if (wdir != NULL)
_Jv_Free (wdir);
} }
catch (java::lang::Throwable *thrown) catch (java::lang::Throwable *thrown)
{ {

View File

@ -7,124 +7,26 @@ Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */ details. */
#include <config.h> #include <config.h>
#include <platform.h>
#ifdef WIN32
#include <windows.h>
#include <winsock.h>
#undef STRICT #undef STRICT
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif /* MAXHOSTNAMELEN */
#else /* WIN32 */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <errno.h>
#include <sys/param.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#endif /* WIN32 */
#include <gcj/cni.h>
#include <jvm.h>
#include <java/net/InetAddress.h> #include <java/net/InetAddress.h>
#include <java/net/UnknownHostException.h> #include <java/net/UnknownHostException.h>
#include <java/lang/SecurityException.h> #include <java/lang/SecurityException.h>
#if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME)
#include <sys/utsname.h>
#endif
#ifndef HAVE_GETHOSTNAME_DECL
extern "C" int gethostname (char *name, int namelen);
#endif
#ifdef DISABLE_JAVA_NET
jbyteArray
java::net::InetAddress::aton (jstring)
{
return NULL;
}
jint
java::net::InetAddress::getFamily (jbyteArray bytes)
{
return 0;
}
JArray<java::net::InetAddress*> *
java::net::InetAddress::lookup (jstring, java::net::InetAddress *, jboolean)
{
return NULL;
}
jstring
java::net::InetAddress::getLocalHostname ()
{
return NULL;
}
#else /* DISABLE_JAVA_NET */
jbyteArray jbyteArray
java::net::InetAddress::aton (jstring host) java::net::InetAddress::aton (jstring host)
{ {
char *hostname; JV_TEMP_UTF_STRING (hostname, host);
char buf[100];
int len = JvGetStringUTFLength(host);
if (len < 100)
hostname = buf;
else
hostname = (char*) _Jv_AllocBytes (len+1);
JvGetStringUTFRegion (host, 0, host->length(), hostname);
buf[len] = '\0';
char* bytes = NULL; char* bytes = NULL;
int blen = 0; int blen = 0;
#ifdef HAVE_INET_ATON unsigned long laddr = inet_addr (hostname);
struct in_addr laddr; if (laddr != INADDR_NONE)
if (inet_aton (hostname, &laddr))
{ {
bytes = (char*) &laddr; bytes = (char*) &laddr;
blen = 4; blen = 4;
} }
#elif defined(HAVE_INET_ADDR)
#if ! HAVE_IN_ADDR_T
typedef jint in_addr_t;
#endif
in_addr_t laddr = inet_addr (hostname);
if (laddr != (in_addr_t)(-1))
{
bytes = (char*) &laddr;
blen = 4;
}
#endif
#if defined (HAVE_INET_PTON) && defined (HAVE_INET6)
char inet6_addr[16];
if (len != 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0)
{
bytes = inet6_addr;
blen = 16;
}
#endif
if (blen == 0) if (blen == 0)
return NULL; return NULL;
jbyteArray result = JvNewByteArray (blen); jbyteArray result = JvNewByteArray (blen);
@ -149,69 +51,17 @@ java::net::InetAddress::getFamily (jbyteArray bytes)
JArray<java::net::InetAddress*> * JArray<java::net::InetAddress*> *
java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr, java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
jboolean all) jboolean all)
{ {
struct hostent *hptr = NULL; struct hostent *hptr = NULL;
#if defined (HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR_R)
struct hostent hent_r;
#if HAVE_STRUCT_HOSTENT_DATA
struct hostent_data fixed_buffer, *buffer_r = &fixed_buffer;
#else
#if defined (__GLIBC__)
// FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and
// ERANGE to errno if the buffer size is too small, rather than what is
// expected here. We work around this by setting a bigger buffer size and
// hoping that it is big enough.
char fixed_buffer[1024];
#else
char fixed_buffer[200];
#endif
char *buffer_r = fixed_buffer;
int size_r = sizeof (fixed_buffer);
#endif
#endif
if (host != NULL) if (host != NULL)
{ {
char *hostname; JV_TEMP_UTF_STRING (hostname, host);
char buf[100];
int len = JvGetStringUTFLength(host);
if (len < 100)
hostname = buf;
else
hostname = (char*) _Jv_AllocBytes (len+1);
JvGetStringUTFRegion (host, 0, host->length(), hostname);
buf[len] = '\0';
#ifdef HAVE_GETHOSTBYNAME_R
while (true)
{
int ok;
#if HAVE_STRUCT_HOSTENT_DATA
ok = ! gethostbyname_r (hostname, &hent_r, buffer_r);
#else
int herr = 0;
#ifdef GETHOSTBYNAME_R_RETURNS_INT
ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r,
&hptr, &herr);
#else
hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr);
ok = hptr != NULL;
#endif /* GETHOSTNAME_R_RETURNS_INT */
if (! ok && herr == ERANGE)
{
size_r *= 2;
buffer_r = (char *) _Jv_AllocBytes (size_r);
}
else
#endif /* HAVE_STRUCT_HOSTENT_DATA */
break;
}
#else
// FIXME: this is insufficient if some other piece of code calls // FIXME: this is insufficient if some other piece of code calls
// this gethostbyname. // this gethostbyname.
JvSynchronize sync (java::net::InetAddress::localhostAddress); JvSynchronize sync (java::net::InetAddress::localhostAddress);
hptr = gethostbyname (hostname); hptr = gethostbyname (hostname);
#endif /* HAVE_GETHOSTBYNAME_R */
} }
else else
{ {
@ -221,51 +71,24 @@ java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
int type; int type;
char *val; char *val;
if (len == 4) if (len == 4)
{ {
val = chars; val = chars;
type = iaddr->family = AF_INET; type = iaddr->family = AF_INET;
} }
#ifdef HAVE_INET6 #ifdef HAVE_INET6
else if (len == 16) else if (len == 16)
{ {
val = (char *) &chars; val = (char *) &chars;
type = iaddr->family = AF_INET6; type = iaddr->family = AF_INET6;
} }
#endif /* HAVE_INET6 */ #endif /* HAVE_INET6 */
else else
JvFail ("unrecognized size"); JvFail ("unrecognized size");
#ifdef HAVE_GETHOSTBYADDR_R
while (true)
{
int ok;
#if HAVE_STRUCT_HOSTENT_DATA
ok = ! gethostbyaddr_r (val, len, type, &hent_r, buffer_r);
#else
int herr = 0;
#ifdef GETHOSTBYADDR_R_RETURNS_INT
ok = ! gethostbyaddr_r (val, len, type, &hent_r,
buffer_r, size_r, &hptr, &herr);
#else
hptr = gethostbyaddr_r (val, len, type, &hent_r,
buffer_r, size_r, &herr);
ok = hptr != NULL;
#endif /* GETHOSTBYADDR_R_RETURNS_INT */
if (! ok && herr == ERANGE)
{
size_r *= 2;
buffer_r = (char *) _Jv_AllocBytes (size_r);
}
else
#endif /* HAVE_STRUCT_HOSTENT_DATA */
break;
}
#else /* HAVE_GETHOSTBYADDR_R */
// FIXME: this is insufficient if some other piece of code calls // FIXME: this is insufficient if some other piece of code calls
// this gethostbyaddr. // this gethostbyaddr.
JvSynchronize sync (java::net::InetAddress::localhostAddress); JvSynchronize sync (java::net::InetAddress::localhostAddress);
hptr = gethostbyaddr (val, len, type); hptr = gethostbyaddr (val, len, type);
#endif /* HAVE_GETHOSTBYADDR_R */
} }
if (hptr != NULL) if (hptr != NULL)
{ {
@ -273,22 +96,23 @@ java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
host = JvNewStringUTF (hptr->h_name); host = JvNewStringUTF (hptr->h_name);
java::lang::SecurityException *ex = checkConnect (host); java::lang::SecurityException *ex = checkConnect (host);
if (ex != NULL) if (ex != NULL)
{ {
if (iaddr == NULL || iaddr->addr == NULL) if (iaddr == NULL || iaddr->addr == NULL)
throw ex; throw ex;
hptr = NULL; hptr = NULL;
} }
} }
if (hptr == NULL) if (hptr == NULL)
{ {
if (iaddr != NULL && iaddr->addr != NULL) if (iaddr != NULL && iaddr->addr != NULL)
{ {
iaddr->hostName = iaddr->getHostAddress(); iaddr->hostName = iaddr->getHostAddress();
return NULL; return NULL;
} }
else else
throw new java::net::UnknownHostException(host); throw new java::net::UnknownHostException(host);
} }
int count; int count;
if (all) if (all)
{ {
@ -298,6 +122,7 @@ java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
} }
else else
count = 1; count = 1;
JArray<java::net::InetAddress*> *result; JArray<java::net::InetAddress*> *result;
java::net::InetAddress** iaddrs; java::net::InetAddress** iaddrs;
if (all) if (all)
@ -314,42 +139,30 @@ java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
if (iaddrs[i] == NULL) if (iaddrs[i] == NULL)
iaddrs[i] = new java::net::InetAddress (NULL, NULL); iaddrs[i] = new java::net::InetAddress (NULL, NULL);
if (iaddrs[i]->hostName == NULL) if (iaddrs[i]->hostName == NULL)
iaddrs[i]->hostName = host; iaddrs[i]->hostName = host;
if (iaddrs[i]->addr == NULL) if (iaddrs[i]->addr == NULL)
{ {
char *bytes = hptr->h_addr_list[i]; char *bytes = hptr->h_addr_list[i];
iaddrs[i]->addr = JvNewByteArray (hptr->h_length); iaddrs[i]->addr = JvNewByteArray (hptr->h_length);
iaddrs[i]->family = getFamily (iaddrs[i]->addr); iaddrs[i]->family = getFamily (iaddrs[i]->addr);
memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length); memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length);
} }
} }
return result; return result;
} }
jstring jstring
java::net::InetAddress::getLocalHostname () java::net::InetAddress::getLocalHostname ()
{ {
char *chars; char buffer[400];
#ifdef HAVE_GETHOSTNAME if (gethostname (buffer, sizeof(buffer)))
char buffer[MAXHOSTNAMELEN];
if (gethostname (buffer, MAXHOSTNAMELEN))
return NULL; return NULL;
chars = buffer;
#elif HAVE_UNAME
struct utsname stuff;
if (uname (&stuff) != 0)
return NULL;
chars = stuff.nodename;
#else
return NULL;
#endif
// It is admittedly non-optimal to convert the hostname to Unicode // It is admittedly non-optimal to convert the hostname to Unicode
// only to convert it back in getByName, but simplicity wins. Note // only to convert it back in getByName, but simplicity wins. Note
// that unless there is a SecurityManager, we only get called once // that unless there is a SecurityManager, we only get called once
// anyway, thanks to the InetAddress.localhost cache. // anyway, thanks to the InetAddress.localhost cache.
return JvNewStringUTF (chars); return JvNewStringUTF (buffer);
} }
#endif /* DISABLE_JAVA_NET */

View File

@ -9,134 +9,126 @@ details. */
#include <config.h> #include <config.h>
#include <platform.h> #include <platform.h>
#ifdef WIN32
#include <windows.h>
#include <winsock.h>
#undef STRICT #undef STRICT
#else /* WIN32 */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/param.h>
#include <sys/types.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#define BSD_COMP /* Get FIONREAD on Solaris2. */
#include <sys/ioctl.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#endif /* WIN32 */
#include <gcj/cni.h>
#include <jvm.h>
#include <java/net/NetworkInterface.h> #include <java/net/NetworkInterface.h>
#include <java/net/Inet4Address.h> #include <java/net/Inet4Address.h>
#include <java/net/SocketException.h> #include <java/net/SocketException.h>
#include <java/util/Vector.h> #include <java/util/Vector.h>
#ifdef DISABLE_JAVA_NET /* As of this writing, NetworkInterface.java has
getName() == getDisplayName() and only one IP address
per interface. If this changes, we'll need to use
iphlpapi (not supported on Win95) to retrieve richer
adapter information via GetAdaptersInfo(). In this
module, we provide the necessary hooks to detect the
presence of iphlpapi and use it if necessary, but
comment things out for now to avoid compiler warnings. */
::java::util::Vector* enum {MAX_INTERFACES = 50};
java::net::NetworkInterface::getRealNetworkInterfaces ()
typedef int
(*PfnGetRealNetworkInterfaces) (jstring* pjstrName,
java::net::InetAddress** ppAddress);
static int
winsock2GetRealNetworkInterfaces (jstring* pjstrName,
java::net::InetAddress** ppAddress)
{ {
::java::util::Vector* ht = new ::java::util::Vector(); // FIXME: Add IPv6 support.
return ht;
} INTERFACE_INFO arInterfaceInfo[MAX_INTERFACES];
#else /* DISABLE_JAVA_NET */
::java::util::Vector*
java::net::NetworkInterface::getRealNetworkInterfaces ()
{
#ifdef WIN32
throw new ::java::net::SocketException;
#else
int fd;
int num_interfaces = 0;
struct ifconf if_data;
struct ifreq* if_record;
::java::util::Vector* ht = new ::java::util::Vector ();
if_data.ifc_len = 0;
if_data.ifc_buf = NULL;
// Open a (random) socket to have a file descriptor for the ioctl calls.
fd = _Jv_socket (PF_INET, SOCK_DGRAM, htons (IPPROTO_IP));
if (fd < 0)
throw new ::java::net::SocketException;
// Get all interfaces. If not enough buffers are available try it
// with a bigger buffer size.
do
{
num_interfaces += 16;
if_data.ifc_len = sizeof (struct ifreq) * num_interfaces;
if_data.ifc_buf =
(char*) _Jv_Realloc (if_data.ifc_buf, if_data.ifc_len);
// Try to get all local interfaces.
if (::ioctl (fd, SIOCGIFCONF, &if_data) < 0)
throw new java::net::SocketException;
}
while (if_data.ifc_len >= (sizeof (struct ifreq) * num_interfaces));
// Open a (random) socket to have a file descriptor for the WSAIoctl call.
SOCKET skt = ::socket (AF_INET, SOCK_DGRAM, 0);
if (skt == INVALID_SOCKET)
_Jv_ThrowSocketException ();
DWORD dwOutBufSize;
int nRetCode = ::WSAIoctl (skt, SIO_GET_INTERFACE_LIST,
NULL, 0, &arInterfaceInfo, sizeof(arInterfaceInfo),
&dwOutBufSize, NULL, NULL);
if (nRetCode == SOCKET_ERROR)
{
DWORD dwLastErrorCode = WSAGetLastError ();
::closesocket (skt);
_Jv_ThrowSocketException (dwLastErrorCode);
}
// Get addresses of all interfaces. // Get addresses of all interfaces.
if_record = if_data.ifc_req; int nNbInterfaces = dwOutBufSize / sizeof(INTERFACE_INFO);
int nCurETHInterface = 0;
for (int n = 0; n < if_data.ifc_len; n += sizeof (struct ifreq)) for (int i=0; i < nNbInterfaces; ++i)
{ {
struct ifreq ifr;
memset (&ifr, 0, sizeof (ifr));
strcpy (ifr.ifr_name, if_record->ifr_name);
// Try to get the IPv4-address of the local interface
if (::ioctl (fd, SIOCGIFADDR, &ifr) < 0)
throw new java::net::SocketException;
int len = 4; int len = 4;
struct sockaddr_in sa = *((sockaddr_in*) &(ifr.ifr_addr));
jbyteArray baddr = JvNewByteArray (len); jbyteArray baddr = JvNewByteArray (len);
memcpy (elements (baddr), &(sa.sin_addr), len); SOCKADDR_IN* pAddr = (SOCKADDR_IN*) &arInterfaceInfo[i].iiAddress;
jstring if_name = JvNewStringLatin1 (if_record->ifr_name); memcpy (elements (baddr), &(pAddr->sin_addr), len);
Inet4Address* address =
// Concoct a name for this interface. Since we don't
// have access to the real name under Winsock 2, we use
// "lo" for the loopback interface and ethX for the
// real ones.
char szName[30];
u_long lFlags = arInterfaceInfo[i].iiFlags;
if (lFlags & IFF_LOOPBACK)
strcpy (szName, "lo");
else
{
strcpy (szName, "eth");
wsprintf(szName+3, "%d", nCurETHInterface++);
}
jstring if_name = JvNewStringLatin1 (szName);
java::net::Inet4Address* address =
new java::net::Inet4Address (baddr, JvNewStringLatin1 ("")); new java::net::Inet4Address (baddr, JvNewStringLatin1 (""));
ht->add (new NetworkInterface (if_name, address)); pjstrName[i] = if_name;
if_record++; ppAddress[i] = address;
} }
#ifdef HAVE_INET6 ::closesocket (skt);
// FIXME: read /proc/net/if_inet6 (on Linux 2.4)
#endif
_Jv_Free (if_data.ifc_buf);
if (fd >= 0) return nNbInterfaces;
_Jv_close (fd);
return ht;
#endif /* WIN32 */
} }
#endif // DISABLE_JAVA_NET // /*
static int
iphlpapiGetRealNetworkInterfaces (jstring* pjstrName,
java::net::InetAddress** ppAddress)
{
return 0;
}
*/
static PfnGetRealNetworkInterfaces
determineGetRealNetworkInterfacesFN ()
{
/* FIXME: Try to dynamically load iphlpapi.dll and
detect the presence of GetAdaptersInfo() using
GetProcAddress(). If successful, return
iphlpapiGetRealNetworkInterfaces; if not,
return winsock2GetRealNetworkInterfaces */
return &winsock2GetRealNetworkInterfaces;
}
::java::util::Vector*
java::net::NetworkInterface::getRealNetworkInterfaces ()
{
static PfnGetRealNetworkInterfaces pfn =
determineGetRealNetworkInterfacesFN ();
jstring arIFName[MAX_INTERFACES];
InetAddress* arpInetAddress[MAX_INTERFACES];
::java::util::Vector* ht = new ::java::util::Vector ();
int nNbInterfaces = (*pfn) (arIFName, arpInetAddress);
for (int i=0; i < nNbInterfaces; ++i)
{
ht->add (new java::net::NetworkInterface (arIFName[i],
arpInetAddress[i]));
}
return ht;
}

View File

@ -8,31 +8,13 @@ details. */
#include <config.h> #include <config.h>
#include <platform.h> #include <platform.h>
#ifdef WIN32
#include <errno.h>
#include <string.h> #include <string.h>
#else /* WIN32 */
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <errno.h>
#include <string.h>
#endif /* WIN32 */
#if HAVE_BSTRING_H #if HAVE_BSTRING_H
// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2 // Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2
#include <bstring.h> #include <bstring.h>
#endif #endif
#include <gcj/cni.h>
#include <java/io/IOException.h> #include <java/io/IOException.h>
#include <java/io/InterruptedIOException.h> #include <java/io/InterruptedIOException.h>
#include <java/net/BindException.h> #include <java/net/BindException.h>
@ -42,116 +24,12 @@ details. */
#include <java/net/NetworkInterface.h> #include <java/net/NetworkInterface.h>
#include <java/net/DatagramPacket.h> #include <java/net/DatagramPacket.h>
#include <java/net/PortUnreachableException.h> #include <java/net/PortUnreachableException.h>
#include <java/net/SocketTimeoutException.h>
#include <java/lang/InternalError.h> #include <java/lang/InternalError.h>
#include <java/lang/Object.h> #include <java/lang/Object.h>
#include <java/lang/Boolean.h> #include <java/lang/Boolean.h>
#include <java/lang/Integer.h> #include <java/lang/Integer.h>
#ifdef DISABLE_JAVA_NET
void
java::net::PlainDatagramSocketImpl::create ()
{
throw new SocketException (
JvNewStringLatin1 ("DatagramSocketImpl.create: unimplemented"));
}
void
java::net::PlainDatagramSocketImpl::bind (jint, java::net::InetAddress *)
{
throw new BindException (
JvNewStringLatin1 ("DatagramSocketImpl.bind: unimplemented"));
}
void
java::net::PlainDatagramSocketImpl::connect (java::net::InetAddress *, jint)
{
throw new SocketException (
JvNewStringLatin1 ("DatagramSocketImpl.connect: unimplemented"));
}
void
java::net::PlainDatagramSocketImpl::disconnect ()
{
throw new SocketException (
JvNewStringLatin1 ("DatagramSocketImpl.disconnect: unimplemented"));
}
jint
java::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *)
{
throw new java::io::IOException (
JvNewStringLatin1 ("DatagramSocketImpl.peek: unimplemented"));
}
jint
java::net::PlainDatagramSocketImpl::peekData(java::net::DatagramPacket *)
{
throw new java::io::IOException (
JvNewStringLatin1 ("DatagramSocketImpl.peekData: unimplemented"));
}
void
java::net::PlainDatagramSocketImpl::close ()
{
throw new java::io::IOException (
JvNewStringLatin1 ("DatagramSocketImpl.close: unimplemented"));
}
void
java::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *)
{
throw new java::io::IOException (
JvNewStringLatin1 ("DatagramSocketImpl.send: unimplemented"));
}
void
java::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *)
{
throw new java::io::IOException (
JvNewStringLatin1 ("DatagramSocketImpl.receive: unimplemented"));
}
void
java::net::PlainDatagramSocketImpl::setTimeToLive (jint)
{
throw new java::io::IOException (
JvNewStringLatin1 ("DatagramSocketImpl.setTimeToLive: unimplemented"));
}
jint
java::net::PlainDatagramSocketImpl::getTimeToLive ()
{
throw new java::io::IOException (
JvNewStringLatin1 ("DatagramSocketImpl.getTimeToLive: unimplemented"));
}
void
java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *,
java::net::NetworkInterface *,
jboolean)
{
throw new java::io::IOException (
JvNewStringLatin1 ("DatagramSocketImpl.mcastGrp: unimplemented"));
}
void
java::net::PlainDatagramSocketImpl::setOption (jint, java::lang::Object *)
{
throw new SocketException (
JvNewStringLatin1 ("DatagramSocketImpl.setOption: unimplemented"));
}
java::lang::Object *
java::net::PlainDatagramSocketImpl::getOption (jint)
{
throw new SocketException (
JvNewStringLatin1 ("DatagramSocketImpl.getOption: unimplemented"));
}
#else /* DISABLE_JAVA_NET */
union SockAddr union SockAddr
{ {
struct sockaddr_in address; struct sockaddr_in address;
@ -178,31 +56,29 @@ union InAddr
#endif #endif
}; };
// FIXME: routines here and/or in natPlainSocketImpl.cc could throw // FIXME: routines here and/or in natPlainSocketImpl.cc could throw
// NoRouteToHostException; also consider UnknownHostException, ConnectException. // NoRouteToHostException; also consider UnknownHostException, ConnectException.
void void
java::net::PlainDatagramSocketImpl::create () java::net::PlainDatagramSocketImpl::create ()
{ {
int sock = _Jv_socket (AF_INET, SOCK_DGRAM, 0); SOCKET sock = ::socket (AF_INET, SOCK_DGRAM, 0);
if (sock < 0) if (sock == INVALID_SOCKET)
{ {
char* strerr = strerror (errno); _Jv_ThrowSocketException ();
throw new java::net::SocketException (JvNewStringUTF (strerr));
} }
_Jv_platform_close_on_exec (sock); _Jv_platform_close_on_exec (sock);
// We use fnum in place of fd here. From leaving fd null we avoid // We use fnum in place of fd here. From leaving fd null we avoid
// the double close problem in FileDescriptor.finalize. // the double close problem in FileDescriptor.finalize.
fnum = sock; fnum = (int) sock;
} }
void void
java::net::PlainDatagramSocketImpl::bind (jint lport, java::net::PlainDatagramSocketImpl::bind (jint lport,
java::net::InetAddress *host) java::net::InetAddress *host)
{ {
union SockAddr u; union SockAddr u;
struct sockaddr *ptr = (struct sockaddr *) &u.address; struct sockaddr *ptr = (struct sockaddr *) &u.address;
@ -235,7 +111,7 @@ java::net::PlainDatagramSocketImpl::bind (jint lport,
else else
throw new java::net::SocketException (JvNewStringUTF ("invalid length")); throw new java::net::SocketException (JvNewStringUTF ("invalid length"));
if (_Jv_bind (fnum, ptr, len) == 0) if (::bind (fnum, ptr, len) == 0)
{ {
socklen_t addrlen = sizeof(u); socklen_t addrlen = sizeof(u);
@ -248,30 +124,30 @@ java::net::PlainDatagramSocketImpl::bind (jint lport,
/* Allow broadcast by default. */ /* Allow broadcast by default. */
int broadcast = 1; int broadcast = 1;
if (::setsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &broadcast, if (::setsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &broadcast,
sizeof (broadcast)) != 0) sizeof (broadcast)) != 0)
goto error; goto error;
return; return;
} }
error: error:
char* strerr = strerror (errno); DWORD dwErrorCode = WSAGetLastError ();
throw new java::net::BindException (JvNewStringUTF (strerr)); throw new java::net::BindException (_Jv_WinStrError (dwErrorCode));
} }
void void
java::net::PlainDatagramSocketImpl::connect (java::net::InetAddress *, jint) java::net::PlainDatagramSocketImpl::connect (java::net::InetAddress *, jint)
{ {
throw new ::java::lang::InternalError (JvNewStringLatin1 ( throw new ::java::lang::InternalError (JvNewStringLatin1 (
"PlainDatagramSocketImpl::connect: not implemented yet")); "PlainDatagramSocketImpl::connect: not implemented yet"));
} }
void void
java::net::PlainDatagramSocketImpl::disconnect () java::net::PlainDatagramSocketImpl::disconnect ()
{ {
throw new ::java::lang::InternalError (JvNewStringLatin1 ( throw new ::java::lang::InternalError (JvNewStringLatin1 (
"PlainDatagramSocketImpl::disconnect: not implemented yet")); "PlainDatagramSocketImpl::disconnect: not implemented yet"));
} }
jint jint
@ -307,13 +183,14 @@ java::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *i)
i->addr = raddr; i->addr = raddr;
return rport; return rport;
error: error:
char* strerr = strerror (errno); DWORD dwErrorCode = WSAGetLastError ();
if (dwErrorCode == WSAECONNRESET)
throw new PortUnreachableException (_Jv_WinStrError (dwErrorCode));
if (errno == ECONNREFUSED) _Jv_ThrowIOException ();
throw new PortUnreachableException (JvNewStringUTF (strerr)); return -1;
// we should never get here
throw new java::io::IOException (JvNewStringUTF (strerr));
} }
jint jint
@ -325,29 +202,18 @@ java::net::PlainDatagramSocketImpl::peekData(java::net::DatagramPacket *p)
jbyte *dbytes = elements (p->getData()); jbyte *dbytes = elements (p->getData());
ssize_t retlen = 0; ssize_t retlen = 0;
// FIXME: implement timeout support for Win32 if (timeout > 0)
#ifndef WIN32
// Do timeouts via select since SO_RCVTIMEO is not always available.
if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
{ {
fd_set rset; int nRet= ::setsockopt(fnum, SOL_SOCKET, SO_RCVTIMEO,
struct timeval tv; (char*)&timeout, sizeof(timeout));
FD_ZERO(&rset); if (nRet != NO_ERROR)
FD_SET(fnum, &rset);
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
int retval;
if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0)
goto error; goto error;
else if (retval == 0)
throw new java::io::InterruptedIOException ();
} }
#endif /* WIN32 */
retlen = retlen =
::recvfrom (fnum, (char *) dbytes, p->getLength(), MSG_PEEK, (sockaddr*) &u, ::recvfrom (fnum, (char *) dbytes, p->getLength(), MSG_PEEK, (sockaddr*) &u,
&addrlen); &addrlen);
if (retlen < 0) if (retlen == SOCKET_ERROR)
goto error; goto error;
// FIXME: Deal with Multicast addressing and if the socket is connected. // FIXME: Deal with Multicast addressing and if the socket is connected.
jbyteArray raddr; jbyteArray raddr;
@ -374,13 +240,17 @@ java::net::PlainDatagramSocketImpl::peekData(java::net::DatagramPacket *p)
p->setLength ((jint) retlen); p->setLength ((jint) retlen);
return rport; return rport;
error: error:
char* strerr = strerror (errno); DWORD dwErrorCode = WSAGetLastError ();
if (dwErrorCode == WSAECONNRESET)
throw new PortUnreachableException (_Jv_WinStrError (dwErrorCode));
else if (dwErrorCode == WSAETIMEDOUT)
throw new java::net::SocketTimeoutException (_Jv_WinStrError (dwErrorCode));
else
_Jv_ThrowIOException ();
if (errno == ECONNREFUSED) return -1;
throw new PortUnreachableException (JvNewStringUTF (strerr)); // we should never get here
throw new java::io::IOException (JvNewStringUTF (strerr));
} }
// Close(shutdown) the socket. // Close(shutdown) the socket.
@ -392,7 +262,7 @@ java::net::PlainDatagramSocketImpl::close ()
// The method isn't declared to throw anything, so we disregard // The method isn't declared to throw anything, so we disregard
// the return value. // the return value.
_Jv_close (fnum); ::closesocket (fnum);
fnum = -1; fnum = -1;
timeout = 0; timeout = 0;
} }
@ -430,12 +300,11 @@ java::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *p)
if (::sendto (fnum, (char *) dbytes, p->getLength(), 0, ptr, len) >= 0) if (::sendto (fnum, (char *) dbytes, p->getLength(), 0, ptr, len) >= 0)
return; return;
char* strerr = strerror (errno); DWORD dwErrorCode = WSAGetLastError ();
if (dwErrorCode == WSAECONNRESET)
throw new PortUnreachableException (_Jv_WinStrError (dwErrorCode));
if (errno == ECONNREFUSED) _Jv_ThrowIOException ();
throw new PortUnreachableException (JvNewStringUTF (strerr));
throw new java::io::IOException (JvNewStringUTF (strerr));
} }
void void
@ -447,24 +316,16 @@ java::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *p)
jbyte *dbytes = elements (p->getData()); jbyte *dbytes = elements (p->getData());
ssize_t retlen = 0; ssize_t retlen = 0;
// FIXME: implement timeout support for Win32 if (timeout > 0)
#ifndef WIN32
// Do timeouts via select since SO_RCVTIMEO is not always available.
if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
{ {
fd_set rset; // This implementation doesn't allow specifying an infinite
struct timeval tv; // timeout after specifying a finite one, but Sun's JDK 1.4.1
FD_ZERO(&rset); // didn't seem to allow this either....
FD_SET(fnum, &rset); int nRet= ::setsockopt(fnum, SOL_SOCKET, SO_RCVTIMEO,
tv.tv_sec = timeout / 1000; (char*)&timeout, sizeof(timeout));
tv.tv_usec = (timeout % 1000) * 1000; if (nRet != NO_ERROR)
int retval;
if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0)
goto error; goto error;
else if (retval == 0)
throw new java::io::InterruptedIOException ();
} }
#endif /* WIN32 */
retlen = retlen =
::recvfrom (fnum, (char *) dbytes, p->getLength(), 0, (sockaddr*) &u, ::recvfrom (fnum, (char *) dbytes, p->getLength(), 0, (sockaddr*) &u,
@ -497,12 +358,13 @@ java::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *p)
return; return;
error: error:
char* strerr = strerror (errno); DWORD dwErrorCode = WSAGetLastError();
if (dwErrorCode == WSAECONNRESET)
if (errno == ECONNREFUSED) throw new PortUnreachableException (_Jv_WinStrError (dwErrorCode));
throw new PortUnreachableException (JvNewStringUTF (strerr)); else if (dwErrorCode == WSAETIMEDOUT)
throw new java::net::SocketTimeoutException (_Jv_WinStrError (dwErrorCode));
throw new java::io::IOException (JvNewStringUTF (strerr)); else
throw new java::io::IOException (_Jv_WinStrError (dwErrorCode));
} }
void void
@ -515,8 +377,7 @@ java::net::PlainDatagramSocketImpl::setTimeToLive (jint ttl)
if (::setsockopt (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, val_len) == 0) if (::setsockopt (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, val_len) == 0)
return; return;
char* strerr = strerror (errno); _Jv_ThrowIOException ();
throw new java::io::IOException (JvNewStringUTF (strerr));
} }
jint jint
@ -529,20 +390,19 @@ java::net::PlainDatagramSocketImpl::getTimeToLive ()
if (::getsockopt (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, &val_len) == 0) if (::getsockopt (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, &val_len) == 0)
return ((int) val) & 0xFF; return ((int) val) & 0xFF;
char* strerr = strerror (errno); _Jv_ThrowIOException ();
throw new java::io::IOException (JvNewStringUTF (strerr));
return -1;
// we should never get here
} }
void void
java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *inetaddr, java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *inetaddr,
java::net::NetworkInterface *, java::net::NetworkInterface *,
jboolean join) jboolean)
{ {
// FIXME: implement use of NetworkInterface // FIXME: implement use of NetworkInterface
union McastReq u;
jbyteArray haddress = inetaddr->addr; jbyteArray haddress = inetaddr->addr;
jbyte *bytes = elements (haddress);
int len = haddress->length; int len = haddress->length;
int level, opname; int level, opname;
const char *ptr; const char *ptr;
@ -556,7 +416,7 @@ java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *inetaddr,
memcpy (&u.mreq.imr_multiaddr, bytes, len); memcpy (&u.mreq.imr_multiaddr, bytes, len);
// FIXME: If a non-default interface is set, use it; see Stevens p. 501. // FIXME: If a non-default interface is set, use it; see Stevens p. 501.
// Maybe not, see note in last paragraph at bottom of Stevens p. 497. // Maybe not, see note in last paragraph at bottom of Stevens p. 497.
u.mreq.imr_interface.s_addr = htonl (INADDR_ANY); u.mreq.imr_interface.s_addr = htonl (INADDR_ANY);
len = sizeof (struct ip_mreq); len = sizeof (struct ip_mreq);
ptr = (const char *) &u.mreq; ptr = (const char *) &u.mreq;
} }
@ -589,13 +449,12 @@ java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *inetaddr,
if (::setsockopt (fnum, level, opname, ptr, len) == 0) if (::setsockopt (fnum, level, opname, ptr, len) == 0)
return; return;
char* strerr = strerror (errno); _Jv_ThrowIOException ();
throw new java::io::IOException (JvNewStringUTF (strerr));
} }
void void
java::net::PlainDatagramSocketImpl::setOption (jint optID, java::net::PlainDatagramSocketImpl::setOption (jint optID,
java::lang::Object *value) java::lang::Object *value)
{ {
int val; int val;
socklen_t val_len = sizeof (val); socklen_t val_len = sizeof (val);
@ -605,19 +464,19 @@ java::net::PlainDatagramSocketImpl::setOption (jint optID,
if (_Jv_IsInstanceOf (value, &java::lang::Boolean::class$)) if (_Jv_IsInstanceOf (value, &java::lang::Boolean::class$))
{ {
java::lang::Boolean *boolobj = java::lang::Boolean *boolobj =
static_cast<java::lang::Boolean *> (value); static_cast<java::lang::Boolean *> (value);
val = boolobj->booleanValue() ? 1 : 0; val = boolobj->booleanValue() ? 1 : 0;
} }
else if (_Jv_IsInstanceOf (value, &java::lang::Integer::class$)) else if (_Jv_IsInstanceOf (value, &java::lang::Integer::class$))
{ {
java::lang::Integer *intobj = java::lang::Integer *intobj =
static_cast<java::lang::Integer *> (value); static_cast<java::lang::Integer *> (value);
val = (int) intobj->intValue(); val = (int) intobj->intValue();
} }
// Else assume value to be an InetAddress for use with IP_MULTICAST_IF. // Else assume value to be an InetAddress for use with IP_MULTICAST_IF.
switch (optID) switch (optID)
{ {
case _Jv_TCP_NODELAY_ : case _Jv_TCP_NODELAY_ :
throw new java::net::SocketException ( throw new java::net::SocketException (
@ -636,103 +495,92 @@ java::net::PlainDatagramSocketImpl::setOption (jint optID,
if (::setsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val, if (::setsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val,
val_len) != 0) val_len) != 0)
goto error; goto error;
break; break;
case _Jv_SO_OOBINLINE_ : case _Jv_SO_OOBINLINE_ :
throw new java::net::SocketException ( throw new java::net::SocketException (
JvNewStringUTF ("SO_OOBINLINE: not valid for UDP")); JvNewStringUTF ("SO_OOBINLINE: not valid for UDP"));
break; break;
case _Jv_SO_SNDBUF_ : case _Jv_SO_SNDBUF_ :
case _Jv_SO_RCVBUF_ : case _Jv_SO_RCVBUF_ :
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
int opt; int opt;
optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF; optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
if (::setsockopt (fnum, SOL_SOCKET, opt, (char *) &val, val_len) != 0) if (::setsockopt (fnum, SOL_SOCKET, opt, (char *) &val, val_len) != 0)
goto error; goto error;
#else
throw new java::lang::InternalError (
JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
#endif
return; return;
case _Jv_SO_REUSEADDR_ : case _Jv_SO_REUSEADDR_ :
#if defined(SO_REUSEADDR) if (::setsockopt (fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
if (::setsockopt (fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &val, val_len) != 0)
val_len) != 0) goto error;
goto error; return;
#else
throw new java::lang::InternalError (
JvNewStringUTF ("SO_REUSEADDR not supported"));
#endif
return;
case _Jv_SO_BINDADDR_ : case _Jv_SO_BINDADDR_ :
throw new java::net::SocketException ( throw new java::net::SocketException (
JvNewStringUTF ("SO_BINDADDR: read only option")); JvNewStringUTF ("SO_BINDADDR: read only option"));
return; return;
case _Jv_IP_MULTICAST_IF_ : case _Jv_IP_MULTICAST_IF_ :
union InAddr u; union InAddr u;
jbyteArray haddress; jbyteArray haddress;
jbyte *bytes; jbyte *bytes;
int len; int len;
int level, opname; int level, opname;
const char *ptr; const char *ptr;
haddress = ((java::net::InetAddress *) value)->addr; haddress = ((java::net::InetAddress *) value)->addr;
bytes = elements (haddress); bytes = elements (haddress);
len = haddress->length; len = haddress->length;
if (len == 4) if (len == 4)
{ {
level = IPPROTO_IP; level = IPPROTO_IP;
opname = IP_MULTICAST_IF; opname = IP_MULTICAST_IF;
memcpy (&u.addr, bytes, len); memcpy (&u.addr, bytes, len);
len = sizeof (struct in_addr); len = sizeof (struct in_addr);
ptr = (const char *) &u.addr; ptr = (const char *) &u.addr;
} }
// Tru64 UNIX V5.0 has struct sockaddr_in6, but no IPV6_MULTICAST_IF // Tru64 UNIX V5.0 has struct sockaddr_in6, but no IPV6_MULTICAST_IF
#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_IF) #if defined (HAVE_INET6) && defined (IPV6_MULTICAST_IF)
else if (len == 16) else if (len == 16)
{ {
level = IPPROTO_IPV6; level = IPPROTO_IPV6;
opname = IPV6_MULTICAST_IF; opname = IPV6_MULTICAST_IF;
memcpy (&u.addr6, bytes, len); memcpy (&u.addr6, bytes, len);
len = sizeof (struct in6_addr); len = sizeof (struct in6_addr);
ptr = (const char *) &u.addr6; ptr = (const char *) &u.addr6;
} }
#endif #endif
else else
throw throw
new java::net::SocketException (JvNewStringUTF ("invalid length")); new java::net::SocketException (JvNewStringUTF ("invalid length"));
if (::setsockopt (fnum, level, opname, ptr, len) != 0) if (::setsockopt (fnum, level, opname, ptr, len) != 0)
goto error; goto error;
return; return;
case _Jv_IP_MULTICAST_IF2_ : case _Jv_IP_MULTICAST_IF2_ :
throw new java::net::SocketException ( throw new java::net::SocketException (
JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented")); JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
break; break;
case _Jv_IP_MULTICAST_LOOP_ : case _Jv_IP_MULTICAST_LOOP_ :
throw new java::net::SocketException ( throw new java::net::SocketException (
JvNewStringUTF ("IP_MULTICAST_LOOP: not yet implemented")); JvNewStringUTF ("IP_MULTICAST_LOOP: not yet implemented"));
break; break;
case _Jv_IP_TOS_ : case _Jv_IP_TOS_ :
if (::setsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, if (::setsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val,
val_len) != 0) val_len) != 0)
goto error; goto error;
return; return;
case _Jv_SO_TIMEOUT_ : case _Jv_SO_TIMEOUT_ :
timeout = val; timeout = val;
return; return;
default : default :
errno = ENOPROTOOPT; WSASetLastError (WSAENOPROTOOPT);
} }
error: error:
char* strerr = strerror (errno); _Jv_ThrowSocketException ();
throw new java::net::SocketException (JvNewStringUTF (strerr));
} }
java::lang::Object * java::lang::Object *
@ -752,121 +600,105 @@ java::net::PlainDatagramSocketImpl::getOption (jint optID)
case _Jv_SO_LINGER_ : case _Jv_SO_LINGER_ :
throw new java::net::SocketException ( throw new java::net::SocketException (
JvNewStringUTF ("SO_LINGER not valid for UDP")); JvNewStringUTF ("SO_LINGER not valid for UDP"));
break; break;
case _Jv_SO_KEEPALIVE_ : case _Jv_SO_KEEPALIVE_ :
throw new java::net::SocketException ( throw new java::net::SocketException (
JvNewStringUTF ("SO_KEEPALIVE not valid for UDP")); JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
break; break;
case _Jv_SO_BROADCAST_ : case _Jv_SO_BROADCAST_ :
if (::getsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val, if (::getsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val,
&val_len) != 0) &val_len) != 0)
goto error; goto error;
return new java::lang::Boolean (val != 0); return new java::lang::Boolean (val != 0);
case _Jv_SO_OOBINLINE_ : case _Jv_SO_OOBINLINE_ :
throw new java::net::SocketException ( throw new java::net::SocketException (
JvNewStringUTF ("SO_OOBINLINE not valid for UDP")); JvNewStringUTF ("SO_OOBINLINE not valid for UDP"));
break; break;
case _Jv_SO_RCVBUF_ : case _Jv_SO_RCVBUF_ :
case _Jv_SO_SNDBUF_ : case _Jv_SO_SNDBUF_ :
#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
int opt; int opt;
optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF; optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
if (::getsockopt (fnum, SOL_SOCKET, opt, (char *) &val, &val_len) != 0) if (::getsockopt (fnum, SOL_SOCKET, opt, (char *) &val, &val_len) != 0)
goto error; goto error;
else else
return new java::lang::Integer (val); return new java::lang::Integer (val);
#else break;
throw new java::lang::InternalError (
JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
#endif
break;
case _Jv_SO_BINDADDR_: case _Jv_SO_BINDADDR_:
// cache the local address // cache the local address
if (localAddress == NULL) if (localAddress == NULL)
{ {
jbyteArray laddr; jbyteArray laddr;
if (::getsockname (fnum, (sockaddr*) &u, &addrlen) != 0) if (::getsockname (fnum, (sockaddr*) &u, &addrlen) != 0)
goto error; goto error;
if (u.address.sin_family == AF_INET) if (u.address.sin_family == AF_INET)
{ {
laddr = JvNewByteArray (4); laddr = JvNewByteArray (4);
memcpy (elements (laddr), &u.address.sin_addr, 4); memcpy (elements (laddr), &u.address.sin_addr, 4);
} }
#ifdef HAVE_INET6 #ifdef HAVE_INET6
else if (u.address.sin_family == AF_INET6) else if (u.address.sin_family == AF_INET6)
{ {
laddr = JvNewByteArray (16); laddr = JvNewByteArray (16);
memcpy (elements (laddr), &u.address6.sin6_addr, 16); memcpy (elements (laddr), &u.address6.sin6_addr, 16);
} }
#endif #endif
else else
throw new java::net::SocketException ( throw new java::net::SocketException (
JvNewStringUTF ("invalid family")); JvNewStringUTF ("invalid family"));
localAddress = new java::net::InetAddress (laddr, NULL); localAddress = new java::net::InetAddress (laddr, NULL);
} }
return localAddress; return localAddress;
break; break;
case _Jv_SO_REUSEADDR_ : case _Jv_SO_REUSEADDR_ :
#if defined(SO_REUSEADDR) if (::getsockopt (fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
if (::getsockopt (fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &val, &val_len) != 0)
&val_len) != 0) goto error;
goto error; return new java::lang::Boolean (val != 0);
return new java::lang::Boolean (val != 0); break;
#else
throw new java::lang::InternalError (
JvNewStringUTF ("SO_REUSEADDR not supported"));
#endif
break;
case _Jv_IP_MULTICAST_IF_ : case _Jv_IP_MULTICAST_IF_ :
#ifdef HAVE_INET_NTOA struct in_addr inaddr;
struct in_addr inaddr; socklen_t inaddr_len;
socklen_t inaddr_len; char *bytes;
char *bytes;
inaddr_len = sizeof(inaddr); inaddr_len = sizeof(inaddr);
if (::getsockopt (fnum, IPPROTO_IP, IP_MULTICAST_IF, (char *) &inaddr, if (::getsockopt (fnum, IPPROTO_IP, IP_MULTICAST_IF, (char *) &inaddr,
&inaddr_len) != 0) &inaddr_len) != 0)
goto error; goto error;
bytes = inet_ntoa (inaddr); bytes = inet_ntoa (inaddr);
return java::net::InetAddress::getByName (JvNewStringLatin1 (bytes)); return java::net::InetAddress::getByName (JvNewStringLatin1 (bytes));
#else break;
throw new java::net::SocketException (
JvNewStringUTF ("IP_MULTICAST_IF: not available - no inet_ntoa()"));
#endif
break;
case _Jv_SO_TIMEOUT_ : case _Jv_SO_TIMEOUT_ :
return new java::lang::Integer (timeout); return new java::lang::Integer (timeout);
break; break;
case _Jv_IP_MULTICAST_IF2_ : case _Jv_IP_MULTICAST_IF2_ :
throw new java::net::SocketException ( throw new java::net::SocketException (
JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented")); JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
break; break;
case _Jv_IP_MULTICAST_LOOP_ : case _Jv_IP_MULTICAST_LOOP_ :
if (::getsockopt (fnum, SOL_SOCKET, IP_MULTICAST_LOOP, (char *) &val, if (::getsockopt (fnum, SOL_SOCKET, IP_MULTICAST_LOOP, (char *) &val,
&val_len) != 0) &val_len) != 0)
goto error; goto error;
return new java::lang::Boolean (val != 0); return new java::lang::Boolean (val != 0);
case _Jv_IP_TOS_ : case _Jv_IP_TOS_ :
if (::getsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, if (::getsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val,
&val_len) != 0) &val_len) != 0)
goto error; goto error;
return new java::lang::Integer (val); return new java::lang::Integer (val);
default : default :
errno = ENOPROTOOPT; WSASetLastError (WSAENOPROTOOPT);
} }
error: error:
char* strerr = strerror (errno); _Jv_ThrowSocketException ();
throw new java::net::SocketException (JvNewStringUTF (strerr)); return 0;
// we should never get here
} }
#endif /* DISABLE_JAVA_NET */

File diff suppressed because it is too large Load Diff

View File

@ -10,11 +10,13 @@ details. */
#include <config.h> #include <config.h>
#include <platform.h> #include <platform.h>
#include <jvm.h>
#include <sys/timeb.h> #include <sys/timeb.h>
#include <stdlib.h> #include <stdlib.h>
#include <java/lang/ArithmeticException.h> #include <java/lang/ArithmeticException.h>
#include <java/lang/UnsupportedOperationException.h>
#include <java/io/IOException.h>
#include <java/net/SocketException.h>
#include <java/util/Properties.h> #include <java/util/Properties.h>
static LONG CALLBACK static LONG CALLBACK
@ -37,6 +39,102 @@ const char *_Jv_ThisExecutable (void)
return exec_name; return exec_name;
} }
// Helper classes and methods implementation
// class WSAEventWrapper
WSAEventWrapper::WSAEventWrapper (int fd, DWORD dwSelFlags):
m_hEvent(0),
m_fd(fd),
m_dwSelFlags(dwSelFlags)
{
m_hEvent = WSACreateEvent ();
if (dwSelFlags)
WSAEventSelect(fd, m_hEvent, dwSelFlags);
}
WSAEventWrapper::~WSAEventWrapper ()
{
if (m_dwSelFlags)
{
WSAEventSelect(m_fd, m_hEvent, 0);
if (m_dwSelFlags & (FD_ACCEPT | FD_CONNECT))
{
// Set the socket back to non-blocking mode.
// Ignore any error since we're in a destructor.
unsigned long lSockOpt = 0L;
// blocking mode
::ioctlsocket (m_fd, FIONBIO, &lSockOpt);
}
}
WSACloseEvent (m_hEvent);
}
// Error string text.
jstring
_Jv_WinStrError (LPCTSTR lpszPrologue, int nErrorCode)
{
LPTSTR lpMsgBuf = 0;
DWORD dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS;
FormatMessage (dwFlags,
NULL,
(DWORD) nErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL);
jstring ret;
if (lpszPrologue)
{
LPTSTR lpszTemp =
(LPTSTR) _Jv_Malloc (strlen (lpszPrologue) +
strlen (lpMsgBuf) + 3);
strcpy (lpszTemp, lpszPrologue);
strcat (lpszTemp, ": ");
strcat (lpszTemp, lpMsgBuf);
ret = JvNewStringLatin1 (lpszTemp);
}
else
{
ret = JvNewStringLatin1 (lpMsgBuf);
}
LocalFree(lpMsgBuf);
return ret;
}
jstring
_Jv_WinStrError (int nErrorCode)
{
return _Jv_WinStrError (0, nErrorCode);
}
void _Jv_ThrowIOException (DWORD dwErrorCode)
{
throw new java::io::IOException (_Jv_WinStrError (dwErrorCode));
}
void _Jv_ThrowIOException()
{
DWORD dwErrorCode = WSAGetLastError ();
_Jv_ThrowIOException (dwErrorCode);
}
void _Jv_ThrowSocketException (DWORD dwErrorCode)
{
throw new java::net::SocketException (_Jv_WinStrError (dwErrorCode));
}
void _Jv_ThrowSocketException()
{
DWORD dwErrorCode = WSAGetLastError ();
_Jv_ThrowSocketException (dwErrorCode);
}
// Platform-specific VM initialization. // Platform-specific VM initialization.
void void
_Jv_platform_initialize (void) _Jv_platform_initialize (void)
@ -45,11 +143,11 @@ _Jv_platform_initialize (void)
WSADATA data; WSADATA data;
if (WSAStartup (MAKEWORD (1, 1), &data)) if (WSAStartup (MAKEWORD (1, 1), &data))
MessageBox (NULL, "Error initialising winsock library.", "Error", MessageBox (NULL, "Error initialising winsock library.", "Error",
MB_OK | MB_ICONEXCLAMATION); MB_OK | MB_ICONEXCLAMATION);
// Install exception handler // Install exception handler
SetUnhandledExceptionFilter (win32_exception_handler); SetUnhandledExceptionFilter (win32_exception_handler);
// Initialize our executable name // Initialize our executable name
GetModuleFileName(NULL, exec_name, sizeof(exec_name)); GetModuleFileName(NULL, exec_name, sizeof(exec_name));
} }
@ -96,14 +194,14 @@ _Jv_platform_initProperties (java::util::Properties* newprops)
if (buffer != NULL) if (buffer != NULL)
{ {
if (GetCurrentDirectory (buflen, buffer)) if (GetCurrentDirectory (buflen, buffer))
SET ("user.dir", buffer); SET ("user.dir", buffer);
if (GetTempPath (buflen, buffer)) if (GetTempPath (buflen, buffer))
SET ("java.io.tmpdir", buffer); SET ("java.io.tmpdir", buffer);
_Jv_Free (buffer); _Jv_Free (buffer);
} }
// Use GetUserName to set 'user.name'. // Use GetUserName to set 'user.name'.
buflen = 257; // UNLEN + 1 buflen = 257; // UNLEN + 1
buffer = (char *) _Jv_MallocUnchecked (buflen); buffer = (char *) _Jv_MallocUnchecked (buflen);
@ -114,8 +212,8 @@ _Jv_platform_initProperties (java::util::Properties* newprops)
_Jv_Free (buffer); _Jv_Free (buffer);
} }
// According to the api documentation for 'GetWindowsDirectory()', the // According to the api documentation for 'GetWindowsDirectory()', the
// environmental variable HOMEPATH always specifies the user's home // environmental variable HOMEPATH always specifies the user's home
// directory or a default directory. On the 3 windows machines I checked // directory or a default directory. On the 3 windows machines I checked
// only 1 had it set. If it's not set, JDK1.3.1 seems to set it to // only 1 had it set. If it's not set, JDK1.3.1 seems to set it to
// the windows directory, so we'll do the same. // the windows directory, so we'll do the same.
@ -130,7 +228,7 @@ _Jv_platform_initProperties (java::util::Properties* newprops)
if (winHome != NULL) if (winHome != NULL)
{ {
if (GetWindowsDirectory (winHome, MAX_PATH)) if (GetWindowsDirectory (winHome, MAX_PATH))
SET ("user.home", winHome); SET ("user.home", winHome);
_Jv_Free (winHome); _Jv_Free (winHome);
} }
} }
@ -148,7 +246,7 @@ _Jv_platform_initProperties (java::util::Properties* newprops)
if (buffer != NULL) if (buffer != NULL)
{ {
sprintf (buffer, "%d.%d", (int) osvi.dwMajorVersion, sprintf (buffer, "%d.%d", (int) osvi.dwMajorVersion,
(int) osvi.dwMinorVersion); (int) osvi.dwMinorVersion);
SET ("os.version", buffer); SET ("os.version", buffer);
_Jv_Free (buffer); _Jv_Free (buffer);
} }
@ -163,7 +261,7 @@ _Jv_platform_initProperties (java::util::Properties* newprops)
else if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) else if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
SET ("os.name", "Windows Me"); SET ("os.name", "Windows Me");
else else
SET ("os.name", "Windows ??"); SET ("os.name", "Windows ??");
break; break;
case VER_PLATFORM_WIN32_NT: case VER_PLATFORM_WIN32_NT:
@ -231,3 +329,16 @@ backtrace (void **__array, int __size)
} }
return i; return i;
} }
int
_Jv_select (int n, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout)
{
int r = ::select (n, readfds, writefds, exceptfds, timeout);
if (r == SOCKET_ERROR)
{
DWORD dwErrorCode = WSAGetLastError ();
throw new java::io::IOException (_Jv_WinStrError (dwErrorCode));
}
return r;
}