Commit 5c144158 by Mohan Embar Committed by Mohan Embar

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
parent a1d6cdc2
2003-08-28 Mohan Embar <gnustuff@thisiscool.com> 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>
* java/net/natInetAddressWin32.cc, * java/net/natInetAddressWin32.cc,
java/net/natNetworkInterfaceWin32.cc, java/net/natNetworkInterfaceWin32.cc,
java/net/natPlainDatagramSocketImplWin32.cc, java/net/natPlainDatagramSocketImplWin32.cc,
......
...@@ -11,11 +11,14 @@ details. */ ...@@ -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. */ ...@@ -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();
WSAEVENT getEventHandle()
{
return m_hEvent;
}
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 ();
#ifndef ENOPROTOOPT extern void
#define ENOPROTOOPT 109 _Jv_ThrowSocketException (DWORD dwErrorCode);
#endif
#endif // DISABLE_JAVA_NET 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) ...@@ -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);
......
...@@ -13,15 +13,13 @@ details. */ ...@@ -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. */ ...@@ -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) ...@@ -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) { ...@@ -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] = "";
jsize total = JvGetStringUTFRegion(path, 0, path->length(), buf); JV_TEMP_UTF_STRING(cpath, path)
buf[total] = '\0';
JvAssert((jflags & READ) || (jflags & WRITE)); JvAssert((jflags & READ) || (jflags & WRITE));
...@@ -118,13 +115,12 @@ java::io::FileDescriptor::open (jstring path, jint jflags) { ...@@ -118,13 +115,12 @@ java::io::FileDescriptor::open (jstring path, jint jflags) {
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) { ...@@ -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;
} }
...@@ -152,10 +151,10 @@ java::io::FileDescriptor::write (jint b) ...@@ -152,10 +151,10 @@ java::io::FileDescriptor::write (jint b)
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
} }
...@@ -179,7 +178,7 @@ java::io::FileDescriptor::write(jbyteArray b, jint offset, jint len) ...@@ -179,7 +178,7 @@ java::io::FileDescriptor::write(jbyteArray b, jint offset, jint len)
} }
} }
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) ...@@ -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
...@@ -203,13 +202,13 @@ java::io::FileDescriptor::setLength(jlong pos) ...@@ -203,13 +202,13 @@ java::io::FileDescriptor::setLength(jlong pos)
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)
{ {
...@@ -219,7 +218,7 @@ java::io::FileDescriptor::setLength(jlong pos) ...@@ -219,7 +218,7 @@ java::io::FileDescriptor::setLength(jlong pos)
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;
} }
...@@ -228,11 +227,11 @@ java::io::FileDescriptor::setLength(jlong pos) ...@@ -228,11 +227,11 @@ java::io::FileDescriptor::setLength(jlong pos)
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)
{ {
...@@ -240,7 +239,7 @@ java::io::FileDescriptor::setLength(jlong pos) ...@@ -240,7 +239,7 @@ java::io::FileDescriptor::setLength(jlong pos)
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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
......
...@@ -9,15 +9,13 @@ Libgcj License. Please consult the file "LIBGCJ_LICENSE" for ...@@ -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. */ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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
...@@ -217,53 +204,42 @@ java::io::File::performList (java::io::FilenameFilter *filter, ...@@ -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) ...@@ -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 () ...@@ -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) ...@@ -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);
......
...@@ -9,18 +9,11 @@ Libgcj License. Please consult the file "LIBGCJ_LICENSE" for ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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)
{ {
......
...@@ -7,124 +7,26 @@ Libgcj License. Please consult the file "LIBGCJ_LICENSE" for ...@@ -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;
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; bytes = (char*) &laddr;
blen = 4; 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);
...@@ -152,66 +54,14 @@ java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr, ...@@ -152,66 +54,14 @@ 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
{ {
...@@ -235,37 +85,10 @@ java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr, ...@@ -235,37 +85,10 @@ java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
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)
{ {
...@@ -289,6 +112,7 @@ java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr, ...@@ -289,6 +112,7 @@ java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
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, ...@@ -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)
...@@ -325,31 +150,19 @@ java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr, ...@@ -325,31 +150,19 @@ java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
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 */
...@@ -9,134 +9,126 @@ details. */ ...@@ -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 ()
{
::java::util::Vector* ht = new ::java::util::Vector();
return ht;
}
#else /* DISABLE_JAVA_NET */ typedef int
(*PfnGetRealNetworkInterfaces) (jstring* pjstrName,
java::net::InetAddress** ppAddress);
::java::util::Vector* static int
java::net::NetworkInterface::getRealNetworkInterfaces () winsock2GetRealNetworkInterfaces (jstring* pjstrName,
java::net::InetAddress** ppAddress)
{ {
#ifdef WIN32 // FIXME: Add IPv6 support.
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; INTERFACE_INFO arInterfaceInfo[MAX_INTERFACES];
if_data.ifc_buf = NULL;
// Open a (random) socket to have a file descriptor for the ioctl calls. // Open a (random) socket to have a file descriptor for the WSAIoctl call.
fd = _Jv_socket (PF_INET, SOCK_DGRAM, htons (IPPROTO_IP)); SOCKET skt = ::socket (AF_INET, SOCK_DGRAM, 0);
if (skt == INVALID_SOCKET)
_Jv_ThrowSocketException ();
if (fd < 0) DWORD dwOutBufSize;
throw new ::java::net::SocketException; int nRetCode = ::WSAIoctl (skt, SIO_GET_INTERFACE_LIST,
NULL, 0, &arInterfaceInfo, sizeof(arInterfaceInfo),
&dwOutBufSize, NULL, NULL);
// Get all interfaces. If not enough buffers are available try it if (nRetCode == SOCKET_ERROR)
// with a bigger buffer size.
do
{ {
num_interfaces += 16; DWORD dwLastErrorCode = WSAGetLastError ();
::closesocket (skt);
if_data.ifc_len = sizeof (struct ifreq) * num_interfaces; _Jv_ThrowSocketException (dwLastErrorCode);
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));
// 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); return nNbInterfaces;
}
if (fd >= 0) /*
_Jv_close (fd); static int
iphlpapiGetRealNetworkInterfaces (jstring* pjstrName,
java::net::InetAddress** ppAddress)
{
return 0;
}
*/
return ht; static PfnGetRealNetworkInterfaces
#endif /* WIN32 */ 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;
} }
#endif // DISABLE_JAVA_NET // ::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;
}
...@@ -8,31 +8,13 @@ details. */ ...@@ -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>
#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> #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. */ ...@@ -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,26 +56,24 @@ union InAddr ...@@ -178,26 +56,24 @@ 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
...@@ -235,7 +111,7 @@ java::net::PlainDatagramSocketImpl::bind (jint lport, ...@@ -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);
...@@ -255,9 +131,9 @@ java::net::PlainDatagramSocketImpl::bind (jint lport, ...@@ -255,9 +131,9 @@ java::net::PlainDatagramSocketImpl::bind (jint lport,
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
...@@ -307,13 +183,14 @@ java::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *i) ...@@ -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)
if (errno == ECONNREFUSED) throw new PortUnreachableException (_Jv_WinStrError (dwErrorCode));
throw new PortUnreachableException (JvNewStringUTF (strerr));
_Jv_ThrowIOException ();
throw new java::io::IOException (JvNewStringUTF (strerr)); return -1;
// we should never get here
} }
jint jint
...@@ -325,29 +202,18 @@ java::net::PlainDatagramSocketImpl::peekData(java::net::DatagramPacket *p) ...@@ -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) ...@@ -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)
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));
else
_Jv_ThrowIOException ();
throw new java::io::IOException (JvNewStringUTF (strerr)); return -1;
// we should never get here
} }
// Close(shutdown) the socket. // Close(shutdown) the socket.
...@@ -392,7 +262,7 @@ java::net::PlainDatagramSocketImpl::close () ...@@ -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) ...@@ -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)
if (errno == ECONNREFUSED) throw new PortUnreachableException (_Jv_WinStrError (dwErrorCode));
throw new PortUnreachableException (JvNewStringUTF (strerr));
throw new java::io::IOException (JvNewStringUTF (strerr)); _Jv_ThrowIOException ();
} }
void void
...@@ -447,24 +316,16 @@ java::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *p) ...@@ -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) ...@@ -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) ...@@ -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 () ...@@ -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;
...@@ -589,8 +449,7 @@ java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *inetaddr, ...@@ -589,8 +449,7 @@ 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
...@@ -645,25 +504,15 @@ java::net::PlainDatagramSocketImpl::setOption (jint optID, ...@@ -645,25 +504,15 @@ java::net::PlainDatagramSocketImpl::setOption (jint optID,
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;
#else
throw new java::lang::InternalError (
JvNewStringUTF ("SO_REUSEADDR not supported"));
#endif
return; return;
case _Jv_SO_BINDADDR_ : case _Jv_SO_BINDADDR_ :
throw new java::net::SocketException ( throw new java::net::SocketException (
...@@ -727,12 +576,11 @@ java::net::PlainDatagramSocketImpl::setOption (jint optID, ...@@ -727,12 +576,11 @@ java::net::PlainDatagramSocketImpl::setOption (jint optID,
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 *
...@@ -771,17 +619,12 @@ java::net::PlainDatagramSocketImpl::getOption (jint optID) ...@@ -771,17 +619,12 @@ java::net::PlainDatagramSocketImpl::getOption (jint optID)
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
throw new java::lang::InternalError (
JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
#endif
break; break;
case _Jv_SO_BINDADDR_: case _Jv_SO_BINDADDR_:
// cache the local address // cache the local address
...@@ -810,18 +653,12 @@ java::net::PlainDatagramSocketImpl::getOption (jint optID) ...@@ -810,18 +653,12 @@ java::net::PlainDatagramSocketImpl::getOption (jint optID)
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);
#else
throw new java::lang::InternalError (
JvNewStringUTF ("SO_REUSEADDR not supported"));
#endif
break; 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;
...@@ -834,10 +671,6 @@ java::net::PlainDatagramSocketImpl::getOption (jint optID) ...@@ -834,10 +671,6 @@ java::net::PlainDatagramSocketImpl::getOption (jint optID)
bytes = inet_ntoa (inaddr); bytes = inet_ntoa (inaddr);
return java::net::InetAddress::getByName (JvNewStringLatin1 (bytes)); return java::net::InetAddress::getByName (JvNewStringLatin1 (bytes));
#else
throw new java::net::SocketException (
JvNewStringUTF ("IP_MULTICAST_IF: not available - no inet_ntoa()"));
#endif
break; break;
case _Jv_SO_TIMEOUT_ : case _Jv_SO_TIMEOUT_ :
return new java::lang::Integer (timeout); return new java::lang::Integer (timeout);
...@@ -861,12 +694,11 @@ java::net::PlainDatagramSocketImpl::getOption (jint optID) ...@@ -861,12 +694,11 @@ java::net::PlainDatagramSocketImpl::getOption (jint optID)
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 */
...@@ -9,61 +9,10 @@ details. */ ...@@ -9,61 +9,10 @@ details. */
#include <config.h> #include <config.h>
#include <platform.h> #include <platform.h>
#ifndef DISABLE_JAVA_NET
#ifdef WIN32
#include <windows.h>
#include <winsock.h>
#include <errno.h>
#include <string.h>
#undef STRICT #undef STRICT
#undef MAX_PRIORITY #undef MAX_PRIORITY
#undef MIN_PRIORITY #undef MIN_PRIORITY
#undef FIONREAD
// These functions make the Win32 socket API look more POSIXy
static inline int
write(int s, void *buf, int len)
{
return send(s, (char*)buf, len, 0);
}
static inline int
read(int s, void *buf, int len)
{
return recv(s, (char*)buf, len, 0);
}
// these errors cannot occur on Win32
#else /* WIN32 */
#ifdef HAVE_SYS_IOCTL_H
#define BSD_COMP /* Get FIONREAD on Solaris2. */
#include <sys/ioctl.h>
#endif
// Pick up FIONREAD on Solaris 2.5.
#ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h>
#endif
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <errno.h>
#include <string.h>
#endif /* WIN32 */
#endif /* DISABLE_JAVA_NET */
#if HAVE_BSTRING_H
// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2
#include <bstring.h>
#endif
#include <gcj/cni.h>
#include <gcj/javaprims.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>
...@@ -83,122 +32,6 @@ read(int s, void *buf, int len) ...@@ -83,122 +32,6 @@ read(int s, void *buf, int len)
#include <java/lang/ArrayIndexOutOfBoundsException.h> #include <java/lang/ArrayIndexOutOfBoundsException.h>
#include <java/lang/IllegalArgumentException.h> #include <java/lang/IllegalArgumentException.h>
#ifdef DISABLE_JAVA_NET
void
java::net::PlainSocketImpl::create (jboolean)
{
throw new java::io::IOException (
JvNewStringLatin1 ("SocketImpl.create: unimplemented"));
}
void
java::net::PlainSocketImpl::bind (java::net::InetAddress *, jint)
{
throw new BindException (
JvNewStringLatin1 ("SocketImpl.bind: unimplemented"));
}
void
java::net::PlainSocketImpl::connect (java::net::SocketAddress *, jint)
{
throw new ConnectException (
JvNewStringLatin1 ("SocketImpl.connect: unimplemented"));
}
void
java::net::PlainSocketImpl::listen (jint)
{
throw new java::io::IOException (
JvNewStringLatin1 ("SocketImpl.listen: unimplemented"));
}
void
java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *)
{
throw new java::io::IOException (
JvNewStringLatin1 ("SocketImpl.accept: unimplemented"));
}
void
java::net::PlainSocketImpl::setOption (jint, java::lang::Object *)
{
throw new SocketException (
JvNewStringLatin1 ("SocketImpl.setOption: unimplemented"));
}
java::lang::Object *
java::net::PlainSocketImpl::getOption (jint)
{
throw new SocketException (
JvNewStringLatin1 ("SocketImpl.getOption: unimplemented"));
}
jint
java::net::PlainSocketImpl::read(void)
{
throw new SocketException (
JvNewStringLatin1 ("SocketImpl.read: unimplemented"));
}
jint
java::net::PlainSocketImpl::read(jbyteArray buffer, jint offset, jint count)
{
throw new SocketException (
JvNewStringLatin1 ("SocketImpl.read: unimplemented"));
}
void
java::net::PlainSocketImpl::write(jint b)
{
throw new SocketException (
JvNewStringLatin1 ("SocketImpl.write: unimplemented"));
}
void
java::net::PlainSocketImpl::write(jbyteArray b, jint offset, jint len)
{
throw new SocketException (
JvNewStringLatin1 ("SocketImpl.write: unimplemented"));
}
void
java::net::PlainSocketImpl::sendUrgentData(jint data)
{
throw new SocketException (
JvNewStringLatin1 ("SocketImpl.sendUrgentData: unimplemented"));
}
jint
java::net::PlainSocketImpl::available(void)
{
throw new SocketException (
JvNewStringLatin1 ("SocketImpl.available: unimplemented"));
}
void
java::net::PlainSocketImpl::close(void)
{
throw new SocketException (
JvNewStringLatin1 ("SocketImpl.close: unimplemented"));
}
void
java::net::PlainSocketImpl::shutdownInput (void)
{
throw new SocketException (
JvNewStringLatin1 ("SocketImpl.shutdownInput: unimplemented"));
}
void
java::net::PlainSocketImpl::shutdownOutput (void)
{
throw new SocketException (
JvNewStringLatin1 ("SocketImpl.shutdownOutput: unimplemented"));
}
#else /* DISABLE_JAVA_NET */
union SockAddr union SockAddr
{ {
struct sockaddr_in address; struct sockaddr_in address;
...@@ -210,12 +43,11 @@ union SockAddr ...@@ -210,12 +43,11 @@ union SockAddr
void void
java::net::PlainSocketImpl::create (jboolean stream) java::net::PlainSocketImpl::create (jboolean stream)
{ {
int sock = _Jv_socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0); int sock = ::socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
if (sock < 0) if (sock == int(INVALID_SOCKET))
{ {
char* strerr = strerror (errno); _Jv_ThrowIOException ();
throw new java::io::IOException (JvNewStringUTF (strerr));
} }
_Jv_platform_close_on_exec (sock); _Jv_platform_close_on_exec (sock);
...@@ -262,14 +94,14 @@ java::net::PlainSocketImpl::bind (java::net::InetAddress *host, jint lport) ...@@ -262,14 +94,14 @@ java::net::PlainSocketImpl::bind (java::net::InetAddress *host, jint lport)
// Enable SO_REUSEADDR, so that servers can reuse ports left in TIME_WAIT. // Enable SO_REUSEADDR, so that servers can reuse ports left in TIME_WAIT.
::setsockopt(fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof(i)); ::setsockopt(fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof(i));
if (_Jv_bind (fnum, ptr, len) == 0) if (::bind (fnum, ptr, len) != SOCKET_ERROR)
{ {
address = host; address = host;
socklen_t addrlen = sizeof(u); socklen_t addrlen = sizeof(u);
if (lport != 0) if (lport != 0)
localport = lport; localport = lport;
else if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0) else if (::getsockname (fnum, (sockaddr*) &u, &addrlen) != SOCKET_ERROR)
localport = ntohs (u.address.sin_port); localport = ntohs (u.address.sin_port);
else else
goto error; goto error;
...@@ -277,9 +109,21 @@ java::net::PlainSocketImpl::bind (java::net::InetAddress *host, jint lport) ...@@ -277,9 +109,21 @@ java::net::PlainSocketImpl::bind (java::net::InetAddress *host, jint lport)
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));
}
static void
throwConnectException (DWORD dwErrorCode)
{
throw new java::net::ConnectException (_Jv_WinStrError (dwErrorCode));
}
static void
throwConnectException ()
{
throwConnectException (WSAGetLastError ());
} }
void void
...@@ -296,6 +140,7 @@ java::net::PlainSocketImpl::connect (java::net::SocketAddress *addr, ...@@ -296,6 +140,7 @@ java::net::PlainSocketImpl::connect (java::net::SocketAddress *addr,
jbyte *bytes = elements (haddress); jbyte *bytes = elements (haddress);
int len = haddress->length; int len = haddress->length;
struct sockaddr *ptr = (struct sockaddr *) &u.address; struct sockaddr *ptr = (struct sockaddr *) &u.address;
if (len == 4) if (len == 4)
{ {
u.address.sin_family = AF_INET; u.address.sin_family = AF_INET;
...@@ -315,35 +160,49 @@ java::net::PlainSocketImpl::connect (java::net::SocketAddress *addr, ...@@ -315,35 +160,49 @@ java::net::PlainSocketImpl::connect (java::net::SocketAddress *addr,
else else
throw new java::net::SocketException (JvNewStringUTF ("invalid length")); throw new java::net::SocketException (JvNewStringUTF ("invalid length"));
// FIXME: implement timeout support for Win32
#ifndef WIN32
if (timeout > 0) if (timeout > 0)
{ {
int flags = ::fcntl (fnum, F_GETFL); // FIXME: we're creating a fresh WSAEVENT for each connect().
::fcntl (fnum, F_SETFL, flags | O_NONBLOCK); WSAEventWrapper aWSAEventWrapper(fnum, FD_CONNECT);
WSAEVENT hEvent = aWSAEventWrapper.getEventHandle ();
if ((_Jv_connect (fnum, ptr, len) != 0) && (errno != EINPROGRESS)) if (::connect (fnum, ptr, len) == SOCKET_ERROR)
goto error; {
if (WSAGetLastError () != WSAEWOULDBLOCK)
throwConnectException ();
fd_set rset; DWORD dwRet =
struct timeval tv; WSAWaitForMultipleEvents (1, &hEvent, true, timeout, false);
FD_ZERO(&rset); // use true, false instead of TRUE, FALSE because the
FD_SET(fnum, &rset); // MS constants got undefined
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
int retval;
if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0) if (dwRet == WSA_WAIT_FAILED)
goto error; throwConnectException ();
else if (retval == 0)
else if (dwRet == WSA_WAIT_TIMEOUT)
throw new java::net::SocketTimeoutException throw new java::net::SocketTimeoutException
(JvNewStringUTF ("Connect timed out")); (JvNewStringUTF ("connect timed out"));
// If we get here, we still need to check whether the actual
// connect() succeeded. Use any socket-specific error code
// instead of the thread-based one.
int nErrCode; int nErrLen=sizeof(nErrCode);
if (::getsockopt(fnum, SOL_SOCKET, SO_ERROR, (char*) &nErrCode,
&nErrLen) == SOCKET_ERROR)
{
throwConnectException ();
}
if (nErrCode != NO_ERROR)
{
throwConnectException (nErrCode);
}
}
} }
else else
#endif
{ {
if (_Jv_connect (fnum, ptr, len) != 0) if (::connect (fnum, ptr, len) == SOCKET_ERROR)
goto error; throwConnectException();
} }
address = host; address = host;
...@@ -352,26 +211,19 @@ java::net::PlainSocketImpl::connect (java::net::SocketAddress *addr, ...@@ -352,26 +211,19 @@ java::net::PlainSocketImpl::connect (java::net::SocketAddress *addr,
// A bind may not have been done on this socket; if so, set localport now. // A bind may not have been done on this socket; if so, set localport now.
if (localport == 0) if (localport == 0)
{ {
if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0) if (::getsockname (fnum, (sockaddr*) &u, &addrlen) != SOCKET_ERROR)
localport = ntohs (u.address.sin_port); localport = ntohs (u.address.sin_port);
else else
goto error; throwConnectException();
} }
return;
error:
char* strerr = strerror (errno);
throw new java::net::ConnectException (JvNewStringUTF (strerr));
} }
void void
java::net::PlainSocketImpl::listen (jint backlog) java::net::PlainSocketImpl::listen (jint backlog)
{ {
if (::listen (fnum, backlog) != 0) if (::listen (fnum, backlog) == SOCKET_ERROR)
{ {
char* strerr = strerror (errno); _Jv_ThrowIOException ();
throw new java::io::IOException (JvNewStringUTF (strerr));
} }
} }
...@@ -382,29 +234,59 @@ java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *s) ...@@ -382,29 +234,59 @@ java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *s)
socklen_t addrlen = sizeof(u); socklen_t addrlen = sizeof(u);
int new_socket = 0; int new_socket = 0;
// FIXME: implement timeout support for Win32 if (timeout > 0)
#ifndef WIN32 {
// Do timeouts via select since SO_RCVTIMEO is not always available. // FIXME: we're creating a fresh WSAEVENT for each accept().
if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE) // One possible alternative would be that fnum really points
{ // to an extended structure consisting of the SOCKET, its
fd_set rset; // associated WSAEVENT, etc.
struct timeval tv; WSAEventWrapper aWSAEventWrapper(fnum, FD_ACCEPT);
FD_ZERO(&rset); WSAEVENT hEvent = aWSAEventWrapper.getEventHandle ();
FD_SET(fnum, &rset);
tv.tv_sec = timeout / 1000; for (;;)
tv.tv_usec = (timeout % 1000) * 1000; {
int retval; new_socket = ::accept (fnum, (sockaddr*) &u, &addrlen);
if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0)
if (new_socket != int(INVALID_SOCKET))
{
// This new child socket is nonblocking because the parent
// socket became nonblocking via the WSAEventSelect() call,
// so we set its mode back to blocking.
WSAEventSelect (new_socket, hEvent, 0);
// undo the hEvent <-> FD_ACCEPT association inherited
// inherited from our parent socket
unsigned long lSockOpt = 0L;
// blocking mode
if (ioctlsocket(new_socket, FIONBIO, &lSockOpt) == SOCKET_ERROR)
{
goto error;
}
break;
}
else if (WSAGetLastError () != WSAEWOULDBLOCK)
{
goto error; goto error;
else if (retval == 0)
throw new java::io::InterruptedIOException (
JvNewStringUTF("Accept timed out"));
} }
#endif /* WIN32 */
new_socket = _Jv_accept (fnum, (sockaddr*) &u, &addrlen); DWORD dwRet =
WSAWaitForMultipleEvents (1, &hEvent, true, timeout, false);
// use true, false instead of TRUE, FALSE because the
// MS constants got undefined
if (new_socket < 0) if (dwRet == WSA_WAIT_FAILED)
goto error;
else if (dwRet == WSA_WAIT_TIMEOUT)
throw new java::net::SocketTimeoutException
(JvNewStringUTF ("accept timed out"));
}
}
else
{
new_socket = ::accept (fnum, (sockaddr*) &u, &addrlen);
}
if (new_socket == int(INVALID_SOCKET))
goto error; goto error;
_Jv_platform_close_on_exec (new_socket); _Jv_platform_close_on_exec (new_socket);
...@@ -435,8 +317,7 @@ java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *s) ...@@ -435,8 +317,7 @@ java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *s)
return; return;
error: error:
char* strerr = strerror (errno); _Jv_ThrowIOException ();
throw new java::io::IOException (JvNewStringUTF (strerr));
} }
// Close(shutdown) the socket. // Close(shutdown) the socket.
...@@ -447,14 +328,16 @@ java::net::PlainSocketImpl::close() ...@@ -447,14 +328,16 @@ java::net::PlainSocketImpl::close()
JvSynchronize sync (this); JvSynchronize sync (this);
// should we use shutdown here? how would that effect so_linger? // should we use shutdown here? how would that effect so_linger?
int res = _Jv_close (fnum); int res = ::closesocket (fnum);
if (res == -1) if (res == -1)
{ {
// These three errors are not errors according to tests performed // These three errors are not errors according to tests performed
// on the reference implementation. // on the reference implementation.
if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF) DWORD dwErr = WSAGetLastError();
throw new java::io::IOException (JvNewStringUTF (strerror (errno))); if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET
&& dwErr != WSAENOTSOCK)
_Jv_ThrowIOException ();
} }
// Safe place to reset the file pointer. // Safe place to reset the file pointer.
fnum = -1; fnum = -1;
...@@ -470,20 +353,22 @@ java::net::PlainSocketImpl::write(jint b) ...@@ -470,20 +353,22 @@ java::net::PlainSocketImpl::write(jint b)
while (r != 1) while (r != 1)
{ {
r = _Jv_write (fnum, &d, 1); r = ::send (fnum, (char*) &d, 1, 0);
if (r == -1) if (r == -1)
{ {
DWORD dwErr = WSAGetLastError();
if (java::lang::Thread::interrupted()) if (java::lang::Thread::interrupted())
{ {
java::io::InterruptedIOException *iioe java::io::InterruptedIOException *iioe
= new java::io::InterruptedIOException = new java::io::InterruptedIOException
(JvNewStringLatin1 (strerror (errno))); (_Jv_WinStrError (dwErr));
iioe->bytesTransferred = 0; iioe->bytesTransferred = 0;
throw iioe; throw iioe;
} }
// Some errors should not cause exceptions. // Some errors should not cause exceptions.
if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF) if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET
throw new java::io::IOException (JvNewStringUTF (strerror (errno))); && dwErr != WSAENOTSOCK)
_Jv_ThrowIOException ();
break; break;
} }
} }
...@@ -500,24 +385,25 @@ java::net::PlainSocketImpl::write(jbyteArray b, jint offset, jint len) ...@@ -500,24 +385,25 @@ java::net::PlainSocketImpl::write(jbyteArray b, jint offset, jint len)
jbyte *bytes = elements (b) + offset; jbyte *bytes = elements (b) + offset;
int written = 0; int written = 0;
while (len > 0) while (len > 0)
{ {
int r = _Jv_write (fnum, bytes, len); int r = ::send (fnum, (char*) bytes, len, 0);
if (r == -1) if (r == -1)
{ {
DWORD dwErr = WSAGetLastError();
if (java::lang::Thread::interrupted()) if (java::lang::Thread::interrupted())
{ {
java::io::InterruptedIOException *iioe java::io::InterruptedIOException *iioe
= new java::io::InterruptedIOException = new java::io::InterruptedIOException
(JvNewStringLatin1 (strerror (errno))); (_Jv_WinStrError (dwErr));
iioe->bytesTransferred = written; iioe->bytesTransferred = written;
throw iioe; throw iioe;
} }
// Some errors should not cause exceptions. // Some errors should not cause exceptions.
if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF) if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET
throw new java::io::IOException (JvNewStringUTF (strerror (errno))); && dwErr != WSAENOTSOCK)
_Jv_ThrowIOException ();
break; break;
} }
...@@ -534,43 +420,37 @@ java::net::PlainSocketImpl::sendUrgentData (jint) ...@@ -534,43 +420,37 @@ java::net::PlainSocketImpl::sendUrgentData (jint)
"PlainSocketImpl: sending of urgent data not supported by this socket")); "PlainSocketImpl: sending of urgent data not supported by this socket"));
} }
// Read a single byte from the socket. // read() helper
jint static jint
java::net::PlainSocketImpl::read(void) doRead(int fnum, void* buf, int count, int timeout)
{ {
jbyte b; int r = 0;
DWORD dwErrorCode = 0;
// FIXME: implement timeout support for Win32 // we are forced to declare this here because
#ifndef WIN32 // a call to Thread::interrupted() blanks out
// Do timeouts via select. // WSAGetLastError().
if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
{ // FIXME: we unconditionally set SO_RCVTIMEO here
// Create the file descriptor set. // because we can't detect whether someone has
fd_set read_fds; // gone from a non-zero to zero timeout. What we'd
FD_ZERO (&read_fds); // really need is a member state variable in addition
FD_SET (fnum,&read_fds); // to timeout
// Create the timeout struct based on our internal timeout value. int nRet= ::setsockopt(fnum, SOL_SOCKET, SO_RCVTIMEO,
struct timeval timeout_value; (char*)&timeout, sizeof(timeout));
timeout_value.tv_sec = timeout / 1000; if (nRet != NO_ERROR)
timeout_value.tv_usec = (timeout % 1000) * 1000; {
// Select on the fds. dwErrorCode = WSAGetLastError ();
int sel_retval = goto error;
_Jv_select (fnum + 1, &read_fds, NULL, NULL, &timeout_value);
// If select returns 0 we've waited without getting data...
// that means we've timed out.
if (sel_retval == 0)
throw new java::io::InterruptedIOException
(JvNewStringUTF ("read timed out") );
// If select returns ok we know we either got signalled or read some data...
// either way we need to try to read.
} }
#endif /* WIN32 */
int r = _Jv_read (fnum, &b, 1); r = ::recv (fnum, (char*) buf, count, 0);
if (r == 0) if (r == 0)
return -1; return -1;
dwErrorCode = WSAGetLastError ();
// save WSAGetLastError() before calling Thread.interrupted()
if (java::lang::Thread::interrupted()) if (java::lang::Thread::interrupted())
{ {
java::io::InterruptedIOException *iioe = java::io::InterruptedIOException *iioe =
...@@ -581,14 +461,28 @@ java::net::PlainSocketImpl::read(void) ...@@ -581,14 +461,28 @@ java::net::PlainSocketImpl::read(void)
} }
else if (r == -1) else if (r == -1)
{ {
error:
// Some errors cause us to return end of stream... // Some errors cause us to return end of stream...
if (errno == ENOTCONN) if (dwErrorCode == WSAENOTCONN)
return -1; return -1;
// Other errors need to be signalled. // Other errors need to be signalled.
throw new java::io::IOException (JvNewStringUTF (strerror (errno))); if (dwErrorCode == WSAETIMEDOUT)
throw new java::net::SocketTimeoutException
(JvNewStringUTF ("read timed out") );
else
_Jv_ThrowIOException (dwErrorCode);
} }
return r;
}
// Read a single byte from the socket.
jint
java::net::PlainSocketImpl::read(void)
{
jbyte b;
doRead(fnum, &b, 1, timeout);
return b & 0xFF; return b & 0xFF;
} }
...@@ -606,120 +500,20 @@ java::net::PlainSocketImpl::read(jbyteArray buffer, jint offset, jint count) ...@@ -606,120 +500,20 @@ java::net::PlainSocketImpl::read(jbyteArray buffer, jint offset, jint count)
jbyte *bytes = elements (buffer) + offset; jbyte *bytes = elements (buffer) + offset;
// FIXME: implement timeout support for Win32
#ifndef WIN32
// Do timeouts via select.
if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
{
// Create the file descriptor set.
fd_set read_fds;
FD_ZERO (&read_fds);
FD_SET (fnum, &read_fds);
// Create the timeout struct based on our internal timeout value.
struct timeval timeout_value;
timeout_value.tv_sec = timeout / 1000;
timeout_value.tv_usec =(timeout % 1000) * 1000;
// Select on the fds.
int sel_retval =
_Jv_select (fnum + 1, &read_fds, NULL, NULL, &timeout_value);
// We're only interested in the 0 return.
// error returns still require us to try to read
// the socket to see what happened.
if (sel_retval == 0)
{
java::io::InterruptedIOException *iioe =
new java::io::InterruptedIOException
(JvNewStringUTF ("read interrupted"));
iioe->bytesTransferred = 0;
throw iioe;
}
}
#endif
// Read the socket. // Read the socket.
int r = ::recv (fnum, (char *) bytes, count, 0); return doRead(fnum, bytes, count, timeout);
if (r == 0)
return -1;
if (java::lang::Thread::interrupted())
{
java::io::InterruptedIOException *iioe =
new java::io::InterruptedIOException
(JvNewStringUTF ("read interrupted"));
iioe->bytesTransferred = r == -1 ? 0 : r;
throw iioe;
}
else if (r == -1)
{
// Some errors cause us to return end of stream...
if (errno == ENOTCONN)
return -1;
// Other errors need to be signalled.
throw new java::io::IOException (JvNewStringUTF (strerror (errno)));
}
return r;
} }
// How many bytes are available? // How many bytes are available?
jint jint
java::net::PlainSocketImpl::available(void) java::net::PlainSocketImpl::available(void)
{ {
#if defined(FIONREAD) || defined(HAVE_SELECT) unsigned long num = 0;
long num = 0;
int r = 0;
bool num_set = false;
#if defined(FIONREAD)
r = ::ioctl (fnum, FIONREAD, &num);
if (r == -1 && errno == ENOTTY)
{
// If the ioctl doesn't work, we don't care.
r = 0;
num = 0;
}
else
num_set = true;
#elif defined(HAVE_SELECT)
if (fnum < 0)
{
errno = EBADF;
r = -1;
}
#endif
if (r == -1)
{
posix_error:
throw new java::io::IOException(JvNewStringUTF(strerror(errno)));
}
// If we didn't get anything we can use select. if (::ioctlsocket (fnum, FIONREAD, &num) == SOCKET_ERROR)
_Jv_ThrowIOException ();
#if defined(HAVE_SELECT)
if (! num_set)
if (! num_set && fnum >= 0 && fnum < FD_SETSIZE)
{
fd_set rd;
FD_ZERO (&rd);
FD_SET (fnum, &rd);
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
r = _Jv_select (fnum + 1, &rd, NULL, NULL, &tv);
if(r == -1)
goto posix_error;
num = r == 0 ? 0 : 1;
}
#endif /* HAVE_SELECT */
return (jint) num; return (jint) num;
#else
throw new java::io::IOException (JvNewStringUTF ("unimplemented"));
#endif
} }
void void
...@@ -760,19 +554,14 @@ java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value) ...@@ -760,19 +554,14 @@ java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value)
switch (optID) switch (optID)
{ {
case _Jv_TCP_NODELAY_ : case _Jv_TCP_NODELAY_ :
#ifdef TCP_NODELAY
if (::setsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val, if (::setsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val,
val_len) != 0) val_len) == SOCKET_ERROR)
goto error; goto error;
#else
throw new java::lang::InternalError
(JvNewStringUTF ("TCP_NODELAY not supported"));
#endif /* TCP_NODELAY */
return; return;
case _Jv_SO_KEEPALIVE_ : case _Jv_SO_KEEPALIVE_ :
if (::setsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val, if (::setsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val,
val_len) != 0) val_len) == SOCKET_ERROR)
goto error; goto error;
break; break;
...@@ -783,36 +572,27 @@ java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value) ...@@ -783,36 +572,27 @@ java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value)
case _Jv_SO_OOBINLINE_ : case _Jv_SO_OOBINLINE_ :
if (::setsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val, if (::setsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val,
val_len) != 0) val_len) == SOCKET_ERROR)
goto error; goto error;
break; break;
case _Jv_SO_LINGER_ : case _Jv_SO_LINGER_ :
#ifdef SO_LINGER
struct linger l_val; struct linger l_val;
l_val.l_onoff = (val != -1); l_val.l_onoff = (val != -1);
l_val.l_linger = val; l_val.l_linger = val;
if (::setsockopt (fnum, SOL_SOCKET, SO_LINGER, (char *) &l_val, if (::setsockopt (fnum, SOL_SOCKET, SO_LINGER, (char *) &l_val,
sizeof(l_val)) != 0) sizeof(l_val)) == SOCKET_ERROR)
goto error; goto error;
#else
throw new java::lang::InternalError (
JvNewStringUTF ("SO_LINGER not supported"));
#endif /* SO_LINGER */
return; return;
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) == SOCKET_ERROR)
goto error; goto error;
#else
throw new java::lang::InternalError (
JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
#endif
return; return;
case _Jv_SO_BINDADDR_ : case _Jv_SO_BINDADDR_ :
...@@ -837,7 +617,7 @@ java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value) ...@@ -837,7 +617,7 @@ java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value)
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) == SOCKET_ERROR)
goto error; goto error;
break; break;
...@@ -851,12 +631,11 @@ java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value) ...@@ -851,12 +631,11 @@ java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value)
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 *
...@@ -871,67 +650,53 @@ java::net::PlainSocketImpl::getOption (jint optID) ...@@ -871,67 +650,53 @@ java::net::PlainSocketImpl::getOption (jint optID)
switch (optID) switch (optID)
{ {
#ifdef TCP_NODELAY
case _Jv_TCP_NODELAY_ : case _Jv_TCP_NODELAY_ :
if (::getsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val, if (::getsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val,
&val_len) != 0) &val_len) == SOCKET_ERROR)
goto error; goto error;
else else
return new java::lang::Boolean (val != 0); return new java::lang::Boolean (val != 0);
#else
throw new java::lang::InternalError
(JvNewStringUTF ("TCP_NODELAY not supported"));
#endif
break; break;
case _Jv_SO_LINGER_ : case _Jv_SO_LINGER_ :
#ifdef SO_LINGER
if (::getsockopt (fnum, SOL_SOCKET, SO_LINGER, (char *) &l_val, if (::getsockopt (fnum, SOL_SOCKET, SO_LINGER, (char *) &l_val,
&l_val_len) != 0) &l_val_len) == SOCKET_ERROR)
goto error; goto error;
if (l_val.l_onoff) if (l_val.l_onoff)
return new java::lang::Integer (l_val.l_linger); return new java::lang::Integer (l_val.l_linger);
else else
return new java::lang::Boolean ((jboolean)false); return new java::lang::Boolean ((jboolean)false);
#else
throw new java::lang::InternalError
(JvNewStringUTF ("SO_LINGER not supported"));
#endif
break; break;
case _Jv_SO_KEEPALIVE_ : case _Jv_SO_KEEPALIVE_ :
if (::getsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val, if (::getsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val,
&val_len) != 0) &val_len) == SOCKET_ERROR)
goto error; goto error;
else else
return new java::lang::Boolean (val != 0); return new java::lang::Boolean (val != 0);
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) == SOCKET_ERROR)
goto error; goto error;
return new java::lang::Boolean ((jboolean)val); return new java::lang::Boolean ((jboolean)val);
case _Jv_SO_OOBINLINE_ : case _Jv_SO_OOBINLINE_ :
if (::getsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val, if (::getsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val,
&val_len) != 0) &val_len) == SOCKET_ERROR)
goto error; goto error;
return new java::lang::Boolean ((jboolean)val); return new java::lang::Boolean ((jboolean)val);
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) == SOCKET_ERROR)
goto error; goto error;
else else
return new java::lang::Integer (val); return new java::lang::Integer (val);
#else
throw new java::lang::InternalError
(JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
#endif
break; break;
case _Jv_SO_BINDADDR_: case _Jv_SO_BINDADDR_:
// cache the local address // cache the local address
...@@ -939,7 +704,8 @@ java::net::PlainSocketImpl::getOption (jint optID) ...@@ -939,7 +704,8 @@ java::net::PlainSocketImpl::getOption (jint optID)
{ {
jbyteArray laddr; jbyteArray laddr;
if (::getsockname (fnum, (sockaddr*) &u, &addrlen) != 0) if (::getsockname (fnum, (sockaddr*) &u,
&addrlen) == SOCKET_ERROR)
goto error; goto error;
if (u.address.sin_family == AF_INET) if (u.address.sin_family == AF_INET)
...@@ -979,7 +745,7 @@ java::net::PlainSocketImpl::getOption (jint optID) ...@@ -979,7 +745,7 @@ java::net::PlainSocketImpl::getOption (jint optID)
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) == SOCKET_ERROR)
goto error; goto error;
return new java::lang::Integer (val); return new java::lang::Integer (val);
break; break;
...@@ -994,26 +760,25 @@ java::net::PlainSocketImpl::getOption (jint optID) ...@@ -994,26 +760,25 @@ java::net::PlainSocketImpl::getOption (jint optID)
break; break;
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
} }
void void
java::net::PlainSocketImpl::shutdownInput (void) java::net::PlainSocketImpl::shutdownInput (void)
{ {
if (::shutdown (fnum, 0)) if (::shutdown (fnum, 0))
throw new SocketException (JvNewStringUTF (strerror (errno))); _Jv_ThrowSocketException ();
} }
void void
java::net::PlainSocketImpl::shutdownOutput (void) java::net::PlainSocketImpl::shutdownOutput (void)
{ {
if (::shutdown (fnum, 1)) if (::shutdown (fnum, 1))
throw new SocketException (JvNewStringUTF (strerror (errno))); _Jv_ThrowSocketException ();
} }
#endif /* DISABLE_JAVA_NET */
...@@ -10,11 +10,13 @@ details. */ ...@@ -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) ...@@ -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)
...@@ -231,3 +329,16 @@ backtrace (void **__array, int __size) ...@@ -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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment