Dead
[official-gcc.git] / gomp-20050608-branch / libjava / gnu / java / net / natPlainSocketImplWin32.cc
blobf54edb5463099f68758f0f29a17b4c46f5d3b49a
1 /* Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 This file is part of libgcj.
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
7 details. */
9 #include <config.h>
10 #include <platform.h>
12 #undef STRICT
13 #undef MAX_PRIORITY
14 #undef MIN_PRIORITY
16 #include <gnu/java/net/PlainSocketImpl.h>
17 #include <gnu/java/net/PlainSocketImpl$SocketInputStream.h>
18 #include <gnu/java/net/PlainSocketImpl$SocketOutputStream.h>
19 #include <java/io/IOException.h>
20 #include <java/net/BindException.h>
21 #include <java/net/ConnectException.h>
22 #include <java/net/InetAddress.h>
23 #include <java/net/InetSocketAddress.h>
24 #include <java/net/SocketException.h>
25 #include <java/net/SocketTimeoutException.h>
26 #include <java/lang/InternalError.h>
27 #include <java/lang/Object.h>
28 #include <java/lang/Boolean.h>
29 #include <java/lang/Class.h>
30 #include <java/lang/Integer.h>
31 #include <java/lang/Thread.h>
32 #include <java/lang/NullPointerException.h>
33 #include <java/lang/ArrayIndexOutOfBoundsException.h>
34 #include <java/lang/IllegalArgumentException.h>
36 union SockAddr
38 struct sockaddr_in address;
39 #ifdef HAVE_INET6
40 struct sockaddr_in6 address6;
41 #endif
44 void
45 gnu::java::net::PlainSocketImpl::create (jboolean stream)
47 SOCKET sock = ::socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
49 if (sock == INVALID_SOCKET)
51 _Jv_ThrowIOException ();
54 // Cast this to a HANDLE so we can make
55 // it non-inheritable via _Jv_platform_close_on_exec.
56 HANDLE hSocket = (HANDLE) sock;
57 _Jv_platform_close_on_exec (hSocket);
59 // We use native_fd in place of fd here. From leaving fd null we avoid
60 // the double close problem in FileDescriptor.finalize.
61 native_fd = (jint) hSocket;
64 void
65 gnu::java::net::PlainSocketImpl::bind (::java::net::InetAddress *host, jint lport)
67 union SockAddr u;
68 struct sockaddr *ptr = (struct sockaddr *) &u.address;
69 jbyteArray haddress = host->addr;
70 jbyte *bytes = elements (haddress);
71 int len = haddress->length;
73 if (len == 4)
75 u.address.sin_family = AF_INET;
77 if (host != NULL)
78 memcpy (&u.address.sin_addr, bytes, len);
79 else
80 u.address.sin_addr.s_addr = htonl (INADDR_ANY);
82 len = sizeof (struct sockaddr_in);
83 u.address.sin_port = htons (lport);
85 #ifdef HAVE_INET6
86 else if (len == 16)
88 u.address6.sin6_family = AF_INET6;
89 memcpy (&u.address6.sin6_addr, bytes, len);
90 len = sizeof (struct sockaddr_in6);
91 u.address6.sin6_port = htons (lport);
93 #endif
94 else
95 throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
97 if (::bind (native_fd, ptr, len) != SOCKET_ERROR)
99 socklen_t addrlen = sizeof(u);
101 if (lport != 0)
102 localport = lport;
103 else if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) != SOCKET_ERROR)
104 localport = ntohs (u.address.sin_port);
105 else
106 goto error;
108 return;
111 error:
112 DWORD dwErrorCode = WSAGetLastError ();
113 throw new ::java::net::BindException (_Jv_WinStrError (dwErrorCode));
116 static void
117 throwConnectException (DWORD dwErrorCode)
119 throw new ::java::net::ConnectException (_Jv_WinStrError (dwErrorCode));
122 static void
123 throwConnectException ()
125 throwConnectException (WSAGetLastError ());
128 void
129 gnu::java::net::PlainSocketImpl::connect (::java::net::SocketAddress *addr,
130 jint timeout)
132 ::java::net::InetSocketAddress *tmp = (::java::net::InetSocketAddress*) addr;
133 ::java::net::InetAddress *host = tmp->getAddress();
134 jint rport = tmp->getPort();
136 // Set the SocketImpl's address and port fields before we try to
137 // connect. Note that the fact that these are set doesn't imply
138 // that we're actually connected to anything. We need to record
139 // this data before we attempt the connect, since non-blocking
140 // SocketChannels will use this and almost certainly throw timeout
141 // exceptions.
142 address = host;
143 port = rport;
145 union SockAddr u;
146 socklen_t addrlen = sizeof(u);
147 jbyteArray haddress = host->addr;
148 jbyte *bytes = elements (haddress);
149 int len = haddress->length;
150 struct sockaddr *ptr = (struct sockaddr *) &u.address;
152 if (len == 4)
154 u.address.sin_family = AF_INET;
155 memcpy (&u.address.sin_addr, bytes, len);
156 len = sizeof (struct sockaddr_in);
157 u.address.sin_port = htons (rport);
159 #ifdef HAVE_INET6
160 else if (len == 16)
162 u.address6.sin6_family = AF_INET6;
163 memcpy (&u.address6.sin6_addr, bytes, len);
164 len = sizeof (struct sockaddr_in6);
165 u.address6.sin6_port = htons (rport);
167 #endif
168 else
169 throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
171 if (timeout > 0)
173 // FIXME: we're creating a fresh WSAEVENT for each connect().
174 WSAEventWrapper aWSAEventWrapper(native_fd, FD_CONNECT);
175 WSAEVENT hEvent = aWSAEventWrapper.getEventHandle ();
177 if (::connect (native_fd, ptr, len) == SOCKET_ERROR)
179 if (WSAGetLastError () != WSAEWOULDBLOCK)
180 throwConnectException ();
182 DWORD dwRet =
183 WSAWaitForMultipleEvents (1, &hEvent, true, timeout, false);
184 // use true, false instead of TRUE, FALSE because the
185 // MS constants got undefined
187 // Reset and ignore our thread's interrupted flag.
188 // It's not possible to interrupt these sort of
189 // operations on Win32 anyway.
190 ::java::lang::Thread::interrupted();
192 if (dwRet == WSA_WAIT_FAILED)
193 throwConnectException ();
194 else if (dwRet == WSA_WAIT_TIMEOUT)
195 throw new ::java::net::SocketTimeoutException
196 (JvNewStringUTF ("connect timed out"));
198 // If we get here, we still need to check whether the actual
199 // connect() succeeded. Use any socket-specific error code
200 // instead of the thread-based one.
201 int nErrCode; int nErrLen=sizeof(nErrCode);
202 if (::getsockopt(native_fd, SOL_SOCKET, SO_ERROR, (char*) &nErrCode,
203 &nErrLen) == SOCKET_ERROR)
205 throwConnectException ();
208 if (nErrCode != NO_ERROR)
210 throwConnectException (nErrCode);
214 else
216 if (::connect (native_fd, ptr, len) == SOCKET_ERROR)
217 throwConnectException();
220 // A bind may not have been done on this socket; if so, set localport now.
221 if (localport == 0)
223 if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) != SOCKET_ERROR)
224 localport = ntohs (u.address.sin_port);
225 else
226 throwConnectException();
230 void
231 gnu::java::net::PlainSocketImpl::listen (jint backlog)
233 if (::listen (native_fd, backlog) == SOCKET_ERROR)
235 _Jv_ThrowIOException ();
239 void
240 gnu::java::net::PlainSocketImpl::accept (gnu::java::net::PlainSocketImpl *s)
242 union SockAddr u;
243 socklen_t addrlen = sizeof(u);
244 HANDLE hSocket = 0;
245 SOCKET new_socket = 0;
247 if (timeout > 0)
249 // FIXME: we're creating a fresh WSAEVENT for each accept().
250 // One possible alternative would be that native_fd really points
251 // to an extended structure consisting of the SOCKET, its
252 // associated WSAEVENT, etc.
253 WSAEventWrapper aWSAEventWrapper(native_fd, FD_ACCEPT);
254 WSAEVENT hEvent = aWSAEventWrapper.getEventHandle ();
256 for (;;)
258 new_socket = ::accept (native_fd, (sockaddr*) &u, &addrlen);
260 if (new_socket != INVALID_SOCKET)
262 // This new child socket is nonblocking because the parent
263 // socket became nonblocking via the WSAEventSelect() call,
264 // so we set its mode back to blocking.
265 WSAEventSelect (new_socket, hEvent, 0);
266 // undo the hEvent <-> FD_ACCEPT association inherited
267 // inherited from our parent socket
269 unsigned long lSockOpt = 0L;
270 // blocking mode
271 if (ioctlsocket(new_socket, FIONBIO, &lSockOpt) == SOCKET_ERROR)
273 goto error;
275 break;
277 else if (WSAGetLastError () != WSAEWOULDBLOCK)
279 goto error;
282 DWORD dwRet =
283 WSAWaitForMultipleEvents (1, &hEvent, true, timeout, false);
284 // use true, false instead of TRUE, FALSE because the
285 // MS constants got undefined
287 // Reset and ignore our thread's interrupted flag.
288 ::java::lang::Thread::interrupted();
290 if (dwRet == WSA_WAIT_FAILED)
291 goto error;
292 else if (dwRet == WSA_WAIT_TIMEOUT)
293 throw new ::java::net::SocketTimeoutException
294 (JvNewStringUTF ("Accept timed out"));
297 else
299 new_socket = ::accept (native_fd, (sockaddr*) &u, &addrlen);
302 if (new_socket == INVALID_SOCKET)
303 goto error;
305 // Cast this to a HANDLE so we can make
306 // it non-inheritable via _Jv_platform_close_on_exec.
307 hSocket = (HANDLE) new_socket;
308 _Jv_platform_close_on_exec (hSocket);
310 jbyteArray raddr;
311 jint rport;
312 if (u.address.sin_family == AF_INET)
314 raddr = JvNewByteArray (4);
315 memcpy (elements (raddr), &u.address.sin_addr, 4);
316 rport = ntohs (u.address.sin_port);
318 #ifdef HAVE_INET6
319 else if (u.address.sin_family == AF_INET6)
321 raddr = JvNewByteArray (16);
322 memcpy (elements (raddr), &u.address6.sin6_addr, 16);
323 rport = ntohs (u.address6.sin6_port);
325 #endif
326 else
327 throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
329 s->native_fd = (jint) hSocket;
330 s->localport = localport;
331 s->address = new ::java::net::InetAddress (raddr, NULL);
332 s->port = rport;
333 return;
335 error:
336 _Jv_ThrowIOException ();
339 // Close(shutdown) the socket.
340 void
341 gnu::java::net::PlainSocketImpl::close()
343 // Avoid races from asynchronous finalization.
344 JvSynchronize sync (this);
346 // should we use shutdown here? how would that effect so_linger?
347 int res = ::closesocket (native_fd);
349 if (res == -1)
351 // These three errors are not errors according to tests performed
352 // on the reference implementation.
353 DWORD dwErr = WSAGetLastError();
354 if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET
355 && dwErr != WSAENOTSOCK)
356 _Jv_ThrowIOException ();
358 // Safe place to reset the file pointer.
359 native_fd = -1;
360 timeout = 0;
363 // Write a byte to the socket.
364 void
365 gnu::java::net::PlainSocketImpl$SocketOutputStream::write(jint b)
367 jbyte d =(jbyte) b;
368 int r = 0;
370 while (r != 1)
372 r = ::send (this$0->native_fd, (char*) &d, 1, 0);
373 if (r == -1)
375 DWORD dwErr = WSAGetLastError();
377 // Reset and ignore our thread's interrupted flag.
378 // It's not possible to interrupt these sort of
379 // operations on Win32 anyway.
380 ::java::lang::Thread::interrupted();
382 // Some errors should not cause exceptions.
383 if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET
384 && dwErr != WSAENOTSOCK)
385 _Jv_ThrowIOException ();
386 break;
391 // Write some bytes to the socket.
392 void
393 gnu::java::net::PlainSocketImpl$SocketOutputStream::write(jbyteArray b,
394 jint offset, jint len)
396 if (! b)
397 throw new ::java::lang::NullPointerException;
398 if (offset < 0 || len < 0 || offset + len > JvGetArrayLength (b))
399 throw new ::java::lang::ArrayIndexOutOfBoundsException;
401 jbyte *bytes = elements (b) + offset;
402 int written = 0;
403 while (len > 0)
405 int r = ::send (this$0->native_fd, (char*) bytes, len, 0);
407 if (r == -1)
409 DWORD dwErr = WSAGetLastError();
411 // Reset and ignore our thread's interrupted flag.
412 ::java::lang::Thread::interrupted();
414 // Some errors should not cause exceptions.
415 if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET
416 && dwErr != WSAENOTSOCK)
417 _Jv_ThrowIOException ();
418 break;
421 written += r;
422 len -= r;
423 bytes += r;
427 void
428 gnu::java::net::PlainSocketImpl::sendUrgentData (jint)
430 throw new ::java::net::SocketException (JvNewStringLatin1 (
431 "PlainSocketImpl: sending of urgent data not supported by this socket"));
434 // read() helper
435 static jint
436 doRead(int native_fd, void* buf, int count, int timeout)
438 int r = 0;
439 DWORD dwErrorCode = 0;
440 // we are forced to declare this here because
441 // a call to Thread::interrupted() blanks out
442 // WSAGetLastError().
444 // FIXME: we unconditionally set SO_RCVTIMEO here
445 // because we can't detect whether someone has
446 // gone from a non-zero to zero timeout. What we'd
447 // really need is a member state variable in addition
448 // to timeout
449 int nRet= ::setsockopt(native_fd, SOL_SOCKET, SO_RCVTIMEO,
450 (char*)&timeout, sizeof(timeout));
451 if (nRet != NO_ERROR)
453 dwErrorCode = WSAGetLastError ();
454 goto error;
457 r = ::recv (native_fd, (char*) buf, count, 0);
459 if (r == 0)
460 return -1;
462 dwErrorCode = WSAGetLastError ();
463 // save WSAGetLastError() before calling Thread.interrupted()
465 // Reset and ignore our thread's interrupted flag.
466 ::java::lang::Thread::interrupted();
468 if (r == -1)
470 error:
471 // Some errors cause us to return end of stream...
472 if (dwErrorCode == WSAENOTCONN)
473 return -1;
475 // Other errors need to be signalled.
476 if (dwErrorCode == WSAETIMEDOUT)
477 throw new ::java::net::SocketTimeoutException
478 (JvNewStringUTF ("Read timed out") );
479 else
480 _Jv_ThrowIOException (dwErrorCode);
483 return r;
486 // Read a single byte from the socket.
487 jint
488 gnu::java::net::PlainSocketImpl$SocketInputStream::read(void)
490 jbyte b;
491 doRead(this$0->native_fd, &b, 1, this$0->timeout);
492 return b & 0xFF;
495 // Read count bytes into the buffer, starting at offset.
496 jint
497 gnu::java::net::PlainSocketImpl$SocketInputStream::read(jbyteArray buffer,
498 jint offset, jint count)
500 // If zero bytes were requested, short circuit so that recv
501 // doesn't signal EOF.
502 if (count == 0)
503 return 0;
505 if (! buffer)
506 throw new ::java::lang::NullPointerException;
508 jsize bsize = JvGetArrayLength (buffer);
510 if (offset < 0 || count < 0 || offset + count > bsize)
511 throw new ::java::lang::ArrayIndexOutOfBoundsException;
513 jbyte *bytes = elements (buffer) + offset;
515 // Read the socket.
516 return doRead(this$0->native_fd, bytes, count, this$0->timeout);
519 // How many bytes are available?
520 jint
521 gnu::java::net::PlainSocketImpl::available(void)
523 unsigned long num = 0;
525 if (::ioctlsocket (native_fd, FIONREAD, &num) == SOCKET_ERROR)
526 _Jv_ThrowIOException ();
528 return (jint) num;
531 void
532 gnu::java::net::PlainSocketImpl::setOption (jint optID, ::java::lang::Object *value)
534 int val;
535 socklen_t val_len = sizeof (val);
537 if (native_fd < 0)
538 throw new ::java::net::SocketException (JvNewStringUTF ("Socket closed"));
540 if (_Jv_IsInstanceOf (value, &::java::lang::Boolean::class$))
542 ::java::lang::Boolean *boolobj =
543 static_cast< ::java::lang::Boolean *> (value);
544 if (boolobj->booleanValue())
545 val = 1;
546 else
548 if (optID == _Jv_SO_LINGER_)
549 val = -1;
550 else
551 val = 0;
554 else if (_Jv_IsInstanceOf (value, &::java::lang::Integer::class$))
556 ::java::lang::Integer *intobj =
557 static_cast< ::java::lang::Integer *> (value);
558 val = (int) intobj->intValue();
560 else
562 throw new ::java::lang::IllegalArgumentException (
563 JvNewStringLatin1 ("`value' must be Boolean or Integer"));
566 switch (optID)
568 case _Jv_TCP_NODELAY_ :
569 if (::setsockopt (native_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &val,
570 val_len) == SOCKET_ERROR)
571 goto error;
572 return;
574 case _Jv_SO_KEEPALIVE_ :
575 if (::setsockopt (native_fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &val,
576 val_len) == SOCKET_ERROR)
577 goto error;
578 break;
580 case _Jv_SO_BROADCAST_ :
581 throw new ::java::net::SocketException
582 (JvNewStringUTF ("SO_BROADCAST not valid for TCP"));
583 break;
585 case _Jv_SO_OOBINLINE_ :
586 if (::setsockopt (native_fd, SOL_SOCKET, SO_OOBINLINE, (char *) &val,
587 val_len) == SOCKET_ERROR)
588 goto error;
589 break;
591 case _Jv_SO_LINGER_ :
592 struct linger l_val;
593 l_val.l_onoff = (val != -1);
594 l_val.l_linger = val;
596 if (::setsockopt (native_fd, SOL_SOCKET, SO_LINGER, (char *) &l_val,
597 sizeof(l_val)) == SOCKET_ERROR)
598 goto error;
599 return;
601 case _Jv_SO_SNDBUF_ :
602 case _Jv_SO_RCVBUF_ :
603 int opt;
604 optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
605 if (::setsockopt (native_fd, SOL_SOCKET, opt, (char *) &val,
606 val_len) == SOCKET_ERROR)
607 goto error;
608 return;
610 case _Jv_SO_BINDADDR_ :
611 throw new ::java::net::SocketException (
612 JvNewStringUTF ("SO_BINDADDR: read only option"));
613 return;
615 case _Jv_IP_MULTICAST_IF_ :
616 throw new ::java::net::SocketException (
617 JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP"));
618 return;
620 case _Jv_IP_MULTICAST_IF2_ :
621 throw new ::java::net::SocketException (
622 JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP"));
623 break;
625 case _Jv_IP_MULTICAST_LOOP_ :
626 throw new ::java::net::SocketException (
627 JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP"));
628 break;
630 case _Jv_IP_TOS_ :
631 if (::setsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val,
632 val_len) == SOCKET_ERROR)
633 goto error;
634 break;
636 case _Jv_SO_REUSEADDR_ :
637 throw new ::java::net::SocketException (
638 JvNewStringUTF ("SO_REUSEADDR: not valid for TCP"));
639 return;
641 case _Jv_SO_TIMEOUT_ :
642 timeout = val;
643 return;
645 default :
646 WSASetLastError (WSAENOPROTOOPT);
649 error:
650 _Jv_ThrowSocketException ();
653 ::java::lang::Object *
654 gnu::java::net::PlainSocketImpl::getOption (jint optID)
656 int val;
657 socklen_t val_len = sizeof(val);
658 union SockAddr u;
659 socklen_t addrlen = sizeof(u);
660 struct linger l_val;
661 socklen_t l_val_len = sizeof(l_val);
663 switch (optID)
665 case _Jv_TCP_NODELAY_ :
666 if (::getsockopt (native_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &val,
667 &val_len) == SOCKET_ERROR)
668 goto error;
669 else
670 return new ::java::lang::Boolean (val != 0);
671 break;
673 case _Jv_SO_LINGER_ :
674 if (::getsockopt (native_fd, SOL_SOCKET, SO_LINGER, (char *) &l_val,
675 &l_val_len) == SOCKET_ERROR)
676 goto error;
678 if (l_val.l_onoff)
679 return new ::java::lang::Integer (l_val.l_linger);
680 else
681 return new ::java::lang::Boolean ((jboolean)false);
682 break;
684 case _Jv_SO_KEEPALIVE_ :
685 if (::getsockopt (native_fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &val,
686 &val_len) == SOCKET_ERROR)
687 goto error;
688 else
689 return new ::java::lang::Boolean (val != 0);
691 case _Jv_SO_BROADCAST_ :
692 if (::getsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &val,
693 &val_len) == SOCKET_ERROR)
694 goto error;
695 return new ::java::lang::Boolean ((jboolean)val);
697 case _Jv_SO_OOBINLINE_ :
698 if (::getsockopt (native_fd, SOL_SOCKET, SO_OOBINLINE, (char *) &val,
699 &val_len) == SOCKET_ERROR)
700 goto error;
701 return new ::java::lang::Boolean ((jboolean)val);
703 case _Jv_SO_RCVBUF_ :
704 case _Jv_SO_SNDBUF_ :
705 int opt;
706 optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
707 if (::getsockopt (native_fd, SOL_SOCKET, opt, (char *) &val,
708 &val_len) == SOCKET_ERROR)
709 goto error;
710 else
711 return new ::java::lang::Integer (val);
712 break;
713 case _Jv_SO_BINDADDR_:
714 // cache the local address
715 if (localAddress == NULL)
717 jbyteArray laddr;
719 if (::getsockname (native_fd, (sockaddr*) &u,
720 &addrlen) == SOCKET_ERROR)
721 goto error;
723 if (u.address.sin_family == AF_INET)
725 laddr = JvNewByteArray (4);
726 memcpy (elements (laddr), &u.address.sin_addr, 4);
728 #ifdef HAVE_INET6
729 else if (u.address.sin_family == AF_INET6)
731 laddr = JvNewByteArray (16);
732 memcpy (elements (laddr), &u.address6.sin6_addr, 16);
734 #endif
735 else
736 throw new ::java::net::SocketException
737 (JvNewStringUTF ("invalid family"));
738 localAddress = new ::java::net::InetAddress (laddr, NULL);
741 return localAddress;
742 break;
743 case _Jv_IP_MULTICAST_IF_ :
744 throw new ::java::net::SocketException
745 (JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP"));
746 break;
748 case _Jv_IP_MULTICAST_IF2_ :
749 throw new ::java::net::SocketException
750 (JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP"));
751 break;
753 case _Jv_IP_MULTICAST_LOOP_ :
754 throw new ::java::net::SocketException
755 (JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP"));
756 break;
758 case _Jv_IP_TOS_ :
759 if (::getsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val,
760 &val_len) == SOCKET_ERROR)
761 goto error;
762 return new ::java::lang::Integer (val);
763 break;
765 case _Jv_SO_REUSEADDR_ :
766 throw new ::java::net::SocketException
767 (JvNewStringUTF ("SO_REUSEADDR: not valid for TCP"));
768 break;
770 case _Jv_SO_TIMEOUT_ :
771 return new ::java::lang::Integer (timeout);
772 break;
774 default :
775 WSASetLastError (WSAENOPROTOOPT);
778 error:
779 _Jv_ThrowSocketException ();
780 return 0;
781 // we should never get here
784 void
785 gnu::java::net::PlainSocketImpl::shutdownInput (void)
787 if (::shutdown (native_fd, 0))
788 _Jv_ThrowSocketException ();
791 void
792 gnu::java::net::PlainSocketImpl::shutdownOutput (void)
794 if (::shutdown (native_fd, 1))
795 _Jv_ThrowSocketException ();