diff options
Diffstat (limited to 'libjava/java/net/natPlainSocketImpl.cc')
-rw-r--r-- | libjava/java/net/natPlainSocketImpl.cc | 187 |
1 files changed, 169 insertions, 18 deletions
diff --git a/libjava/java/net/natPlainSocketImpl.cc b/libjava/java/net/natPlainSocketImpl.cc index 4a75e980073..a1e967eb8b3 100644 --- a/libjava/java/net/natPlainSocketImpl.cc +++ b/libjava/java/net/natPlainSocketImpl.cc @@ -20,13 +20,9 @@ details. */ #undef MIN_PRIORITY #undef FIONREAD -// These functions make the Win32 socket API look more POSIXy -static inline int -close(int s) -{ - return closesocket(s); -} +#define NATIVE_CLOSE(s) closesocket (s) +// These functions make the Win32 socket API look more POSIXy static inline int write(int s, void *buf, int len) { @@ -63,6 +59,8 @@ read(int s, void *buf, int len) #include <errno.h> #include <string.h> +#define NATIVE_CLOSE(s) ::close (s) + #endif /* WIN32 */ #endif /* DISABLE_JAVA_NET */ @@ -120,7 +118,9 @@ _Jv_accept (int fd, struct sockaddr *addr, socklen_t *addrlen) #include <java/net/ConnectException.h> #include <java/net/PlainSocketImpl.h> #include <java/net/InetAddress.h> +#include <java/net/InetSocketAddress.h> #include <java/net/SocketException.h> +#include <java/net/SocketTimeoutException.h> #include <java/lang/InternalError.h> #include <java/lang/Object.h> #include <java/lang/Boolean.h> @@ -148,7 +148,7 @@ java::net::PlainSocketImpl::bind (java::net::InetAddress *, jint) } void -java::net::PlainSocketImpl::connect (java::net::InetAddress *, jint) +java::net::PlainSocketImpl::connect (java::net::SocketAddress *, jint) { throw new ConnectException ( JvNewStringLatin1 ("SocketImpl.connect: unimplemented")); @@ -210,6 +210,13 @@ java::net::PlainSocketImpl::write(jbyteArray b, jint offset, jint len) JvNewStringLatin1 ("SocketImpl.write: unimplemented")); } +void +java::net::PlainSocketImpl::sendUrgentData(jint data) +{ + throw new SocketException ( + JvNewStringLatin1 ("SocketImpl.sendUrgentData: unimplemented")); +} + jint java::net::PlainSocketImpl::available(void) { @@ -224,6 +231,20 @@ java::net::PlainSocketImpl::close(void) 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 @@ -304,8 +325,13 @@ java::net::PlainSocketImpl::bind (java::net::InetAddress *host, jint lport) } void -java::net::PlainSocketImpl::connect (java::net::InetAddress *host, jint rport) +java::net::PlainSocketImpl::connect (java::net::SocketAddress *addr, + jint timeout) { + java::net::InetSocketAddress *tmp = (java::net::InetSocketAddress*) addr; + java::net::InetAddress *host = tmp->getAddress(); + jint rport = tmp->getPort(); + union SockAddr u; socklen_t addrlen = sizeof(u); jbyteArray haddress = host->addr; @@ -331,8 +357,37 @@ java::net::PlainSocketImpl::connect (java::net::InetAddress *host, jint rport) else throw new java::net::SocketException (JvNewStringUTF ("invalid length")); - if (_Jv_connect (fnum, ptr, len) != 0) - goto error; +// FIXME: implement timeout support for Win32 +#ifndef WIN32 + if (timeout > 0) + { + int flags = ::fcntl (fnum, F_GETFL); + ::fcntl (fnum, F_SETFL, flags | O_NONBLOCK); + + if ((_Jv_connect (fnum, ptr, len) != 0) && (errno != EINPROGRESS)) + goto error; + + fd_set rset; + struct timeval tv; + FD_ZERO(&rset); + 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; + else if (retval == 0) + throw new java::net::SocketTimeoutException ( + JvNewStringUTF("Connect timed out")); + } + else +#endif + { + if (_Jv_connect (fnum, ptr, len) != 0) + goto error; + } + address = host; port = rport; // A bind may not have been done on this socket; if so, set localport now. @@ -429,7 +484,7 @@ java::net::PlainSocketImpl::close() JvSynchronize sync (this); // should we use shutdown here? how would that effect so_linger? - int res = ::close (fnum); + int res = NATIVE_CLOSE (fnum); if (res == -1) { @@ -506,6 +561,12 @@ java::net::PlainSocketImpl::write(jbyteArray b, jint offset, jint len) } } +void +java::net::PlainSocketImpl::sendUrgentData (jint) +{ + throw new SocketException (JvNewStringLatin1 ( + "PlainSocketImpl: sending of urgent data not supported by this socket")); +} // Read a single byte from the socket. jint @@ -527,7 +588,8 @@ java::net::PlainSocketImpl::read(void) 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); + int sel_retval = + _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) @@ -586,7 +648,8 @@ java::net::PlainSocketImpl::read(jbyteArray buffer, jint offset, jint count) 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); + 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. @@ -715,7 +778,8 @@ java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value) } else { - throw new java::lang::IllegalArgumentException (JvNewStringLatin1 ("`value' must be Boolean or Integer")); + throw new java::lang::IllegalArgumentException ( + JvNewStringLatin1 ("`value' must be Boolean or Integer")); } switch (optID) @@ -724,12 +788,30 @@ java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value) #ifdef TCP_NODELAY if (::setsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val, val_len) != 0) - goto error; + goto error; #else throw new java::lang::InternalError ( JvNewStringUTF ("TCP_NODELAY not supported")); #endif /* TCP_NODELAY */ return; + + case _Jv_SO_KEEPALIVE_ : + if (::setsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val, + val_len) != 0) + goto error; + break; + + case _Jv_SO_BROADCAST_ : + throw new java::net::SocketException ( + JvNewStringUTF ("SO_BROADCAST not valid for TCP")); + break; + + case _Jv_SO_OOBINLINE_ : + if (::setsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val, + val_len) != 0) + goto error; + break; + case _Jv_SO_LINGER_ : #ifdef SO_LINGER struct linger l_val; @@ -763,6 +845,23 @@ java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value) throw new java::net::SocketException ( JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP")); return; + + case _Jv_IP_MULTICAST_IF2_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP")); + break; + + case _Jv_IP_MULTICAST_LOOP_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP")); + break; + + case _Jv_IP_TOS_ : + if (::setsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, + val_len) != 0) + goto error; + break; + case _Jv_SO_REUSEADDR_ : throw new java::net::SocketException ( JvNewStringUTF ("SO_REUSEADDR: not valid for TCP")); @@ -812,12 +911,32 @@ java::net::PlainSocketImpl::getOption (jint optID) if (l_val.l_onoff) return new java::lang::Integer (l_val.l_linger); else - return new java::lang::Boolean ((__java_boolean)false); + return new java::lang::Boolean ((jboolean)false); #else throw new java::lang::InternalError ( JvNewStringUTF ("SO_LINGER not supported")); #endif break; + + case _Jv_SO_KEEPALIVE_ : + if (::getsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val, + &val_len) != 0) + goto error; + else + return new java::lang::Boolean (val != 0); + + case _Jv_SO_BROADCAST_ : + if (::getsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Boolean ((jboolean)val); + + case _Jv_SO_OOBINLINE_ : + if (::getsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Boolean ((jboolean)val); + case _Jv_SO_RCVBUF_ : case _Jv_SO_SNDBUF_ : #if defined(SO_SNDBUF) && defined(SO_RCVBUF) @@ -852,8 +971,8 @@ java::net::PlainSocketImpl::getOption (jint optID) } #endif else - throw - new java::net::SocketException (JvNewStringUTF ("invalid family")); + throw new java::net::SocketException ( + JvNewStringUTF ("invalid family")); localAddress = new java::net::InetAddress (laddr, NULL); } return localAddress; @@ -862,6 +981,24 @@ java::net::PlainSocketImpl::getOption (jint optID) throw new java::net::SocketException ( JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP")); break; + + case _Jv_IP_MULTICAST_IF2_ : + throw new java::net::SocketException ( + JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP")); + break; + + case _Jv_IP_MULTICAST_LOOP_ : + throw new java::net::SocketException( + JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP")); + break; + + case _Jv_IP_TOS_ : + if (::getsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val, + &val_len) != 0) + goto error; + return new java::lang::Integer (val); + break; + case _Jv_SO_REUSEADDR_ : throw new java::net::SocketException ( JvNewStringUTF ("SO_REUSEADDR: not valid for TCP")); @@ -878,4 +1015,18 @@ java::net::PlainSocketImpl::getOption (jint optID) throw new java::net::SocketException (JvNewStringUTF (strerr)); } +void +java::net::PlainSocketImpl::shutdownInput (void) +{ + if (::shutdown (fnum, 0)) + throw new SocketException (JvNewStringUTF (strerror (errno))); +} + +void +java::net::PlainSocketImpl::shutdownOutput (void) +{ + if (::shutdown (fnum, 1)) + throw new SocketException (JvNewStringUTF (strerror (errno))); +} + #endif /* DISABLE_JAVA_NET */ |