This commit was manufactured by cvs2svn to create branch
[official-gcc.git] / libjava / gnu / java / net / natPlainDatagramSocketImplWin32.cc
blobbda03fb6c39fa3cdabe4bc1ce0a718325243f1b6
1 /* Copyright (C) 2003 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>
11 #include <string.h>
13 #if HAVE_BSTRING_H
14 // Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2
15 #include <bstring.h>
16 #endif
18 #include <gnu/java/net/PlainDatagramSocketImpl.h>
19 #include <java/io/IOException.h>
20 #include <java/net/BindException.h>
21 #include <java/net/SocketException.h>
22 #include <java/net/InetAddress.h>
23 #include <java/net/NetworkInterface.h>
24 #include <java/net/DatagramPacket.h>
25 #include <java/net/PortUnreachableException.h>
26 #include <java/net/SocketTimeoutException.h>
27 #include <java/lang/InternalError.h>
28 #include <java/lang/Object.h>
29 #include <java/lang/Boolean.h>
30 #include <java/lang/Integer.h>
32 union SockAddr
34 struct sockaddr_in address;
35 #ifdef HAVE_INET6
36 struct sockaddr_in6 address6;
37 #endif
40 union McastReq
42 #if HAVE_STRUCT_IP_MREQ
43 struct ip_mreq mreq;
44 #endif
45 #if HAVE_STRUCT_IPV6_MREQ
46 struct ipv6_mreq mreq6;
47 #endif
50 union InAddr
52 struct in_addr addr;
53 #ifdef HAVE_INET6
54 struct in6_addr addr6;
55 #endif
58 // FIXME: routines here and/or in natPlainSocketImpl.cc could throw
59 // NoRouteToHostException; also consider UnknownHostException, ConnectException.
61 void
62 gnu::java::net::PlainDatagramSocketImpl::create ()
64 SOCKET sock = ::socket (AF_INET, SOCK_DGRAM, 0);
66 if (sock == INVALID_SOCKET)
68 _Jv_ThrowSocketException ();
71 // Cast this to a HANDLE so we can make
72 // it non-inheritable via _Jv_platform_close_on_exec.
73 HANDLE hSocket = (HANDLE) sock;
74 _Jv_platform_close_on_exec (hSocket);
76 // We use native_fd in place of fd here. From leaving fd null we avoid
77 // the double close problem in FileDescriptor.finalize.
78 native_fd = (jint) hSocket;
81 void
82 gnu::java::net::PlainDatagramSocketImpl::bind (jint lport,
83 ::java::net::InetAddress *host)
85 union SockAddr u;
86 struct sockaddr *ptr = (struct sockaddr *) &u.address;
87 // FIXME: Use getaddrinfo() to get actual protocol instead of assuming ipv4.
88 jbyteArray haddress = host->addr;
89 jbyte *bytes = elements (haddress);
90 int len = haddress->length;
92 if (len == 4)
94 u.address.sin_family = AF_INET;
96 if (host != NULL)
97 memcpy (&u.address.sin_addr, bytes, len);
98 else
99 u.address.sin_addr.s_addr = htonl (INADDR_ANY);
101 len = sizeof (struct sockaddr_in);
102 u.address.sin_port = htons (lport);
104 #ifdef HAVE_INET6
105 else if (len == 16)
107 u.address6.sin6_family = AF_INET6;
108 memcpy (&u.address6.sin6_addr, bytes, len);
109 len = sizeof (struct sockaddr_in6);
110 u.address6.sin6_port = htons (lport);
112 #endif
113 else
114 throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
116 if (::bind (native_fd, ptr, len) == 0)
118 socklen_t addrlen = sizeof(u);
120 if (lport != 0)
121 localPort = lport;
122 else if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) == 0)
123 localPort = ntohs (u.address.sin_port);
124 else
125 goto error;
127 /* Allow broadcast by default. */
128 int broadcast = 1;
129 if (::setsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &broadcast,
130 sizeof (broadcast)) != 0)
131 goto error;
133 return;
136 error:
137 DWORD dwErrorCode = WSAGetLastError ();
138 throw new ::java::net::BindException (_Jv_WinStrError (dwErrorCode));
141 void
142 gnu::java::net::PlainDatagramSocketImpl::connect (::java::net::InetAddress *, jint)
144 throw new ::java::lang::InternalError (JvNewStringLatin1 (
145 "PlainDatagramSocketImpl::connect: not implemented yet"));
148 void
149 gnu::java::net::PlainDatagramSocketImpl::disconnect ()
151 throw new ::java::lang::InternalError (JvNewStringLatin1 (
152 "PlainDatagramSocketImpl::disconnect: not implemented yet"));
155 jint
156 gnu::java::net::PlainDatagramSocketImpl::peek (::java::net::InetAddress *i)
158 // FIXME: Deal with Multicast and if the socket is connected.
159 union SockAddr u;
160 socklen_t addrlen = sizeof(u);
161 ssize_t retlen =
162 ::recvfrom (native_fd, (char *) NULL, 0, MSG_PEEK, (sockaddr*) &u,
163 &addrlen);
164 if (retlen < 0)
165 goto error;
166 // FIXME: Deal with Multicast addressing and if the socket is connected.
167 jbyteArray raddr;
168 jint rport;
169 if (u.address.sin_family == AF_INET)
171 raddr = JvNewByteArray (4);
172 memcpy (elements (raddr), &u.address.sin_addr, 4);
173 rport = ntohs (u.address.sin_port);
175 #ifdef HAVE_INET6
176 else if (u.address.sin_family == AF_INET6)
178 raddr = JvNewByteArray (16);
179 memcpy (elements (raddr), &u.address6.sin6_addr, 16);
180 rport = ntohs (u.address6.sin6_port);
182 #endif
183 else
184 throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
186 i->addr = raddr;
187 return rport;
188 error:
189 DWORD dwErrorCode = WSAGetLastError ();
190 if (dwErrorCode == WSAECONNRESET)
191 throw new ::java::net::PortUnreachableException (_Jv_WinStrError (dwErrorCode));
193 _Jv_ThrowIOException ();
194 return -1;
195 // we should never get here
198 jint
199 gnu::java::net::PlainDatagramSocketImpl::peekData(::java::net::DatagramPacket *p)
201 // FIXME: Deal with Multicast and if the socket is connected.
202 union SockAddr u;
203 socklen_t addrlen = sizeof(u);
204 jbyte *dbytes = elements (p->getData()) + p->getOffset();
205 jint maxlen = p->maxlen - p->getOffset();
206 ssize_t retlen = 0;
208 if (timeout > 0)
210 int nRet= ::setsockopt(native_fd, SOL_SOCKET, SO_RCVTIMEO,
211 (char*)&timeout, sizeof(timeout));
212 if (nRet != NO_ERROR)
213 goto error;
216 retlen =
217 ::recvfrom (native_fd, (char *) dbytes, maxlen, MSG_PEEK, (sockaddr*) &u,
218 &addrlen);
219 if (retlen == SOCKET_ERROR)
220 goto error;
221 // FIXME: Deal with Multicast addressing and if the socket is connected.
222 jbyteArray raddr;
223 jint rport;
224 if (u.address.sin_family == AF_INET)
226 raddr = JvNewByteArray (4);
227 memcpy (elements (raddr), &u.address.sin_addr, 4);
228 rport = ntohs (u.address.sin_port);
230 #ifdef HAVE_INET6
231 else if (u.address.sin_family == AF_INET6)
233 raddr = JvNewByteArray (16);
234 memcpy (elements (raddr), &u.address6.sin6_addr, 16);
235 rport = ntohs (u.address6.sin6_port);
237 #endif
238 else
239 throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
241 p->setAddress (new ::java::net::InetAddress (raddr, NULL));
242 p->setPort (rport);
243 p->length = (jint) retlen;
244 return rport;
246 error:
247 DWORD dwErrorCode = WSAGetLastError ();
248 if (dwErrorCode == WSAECONNRESET)
249 throw new ::java::net::PortUnreachableException (_Jv_WinStrError (dwErrorCode));
250 else if (dwErrorCode == WSAETIMEDOUT)
251 throw new ::java::net::SocketTimeoutException (_Jv_WinStrError (dwErrorCode));
252 else
253 _Jv_ThrowIOException ();
255 return -1;
256 // we should never get here
259 // Close(shutdown) the socket.
260 void
261 gnu::java::net::PlainDatagramSocketImpl::close ()
263 // Avoid races from asynchronous finalization.
264 JvSynchronize sync (this);
266 // The method isn't declared to throw anything, so we disregard
267 // the return value.
268 ::closesocket (native_fd);
269 native_fd = -1;
270 timeout = 0;
273 void
274 gnu::java::net::PlainDatagramSocketImpl::send (::java::net::DatagramPacket *p)
276 JvSynchronize lock (SEND_LOCK);
278 // FIXME: Deal with Multicast and if the socket is connected.
279 jint rport = p->getPort();
280 union SockAddr u;
281 jbyteArray haddress = p->getAddress()->addr;
282 jbyte *bytes = elements (haddress);
283 int len = haddress->length;
284 struct sockaddr *ptr = (struct sockaddr *) &u.address;
285 jbyte *dbytes = elements (p->getData()) + p->getOffset();
286 if (len == 4)
288 u.address.sin_family = AF_INET;
289 memcpy (&u.address.sin_addr, bytes, len);
290 len = sizeof (struct sockaddr_in);
291 u.address.sin_port = htons (rport);
293 #ifdef HAVE_INET6
294 else if (len == 16)
296 u.address6.sin6_family = AF_INET6;
297 memcpy (&u.address6.sin6_addr, bytes, len);
298 len = sizeof (struct sockaddr_in6);
299 u.address6.sin6_port = htons (rport);
301 #endif
302 else
303 throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
305 if (::sendto (native_fd, (char *) dbytes, p->getLength(), 0, ptr, len) >= 0)
306 return;
308 DWORD dwErrorCode = WSAGetLastError ();
309 if (dwErrorCode == WSAECONNRESET)
310 throw new ::java::net::PortUnreachableException (_Jv_WinStrError (dwErrorCode));
312 _Jv_ThrowIOException ();
315 void
316 gnu::java::net::PlainDatagramSocketImpl::receive (::java::net::DatagramPacket *p)
318 JvSynchronize lock (RECEIVE_LOCK);
320 // FIXME: Deal with Multicast and if the socket is connected.
321 union SockAddr u;
322 socklen_t addrlen = sizeof(u);
323 jbyte *dbytes = elements (p->getData()) + p->getOffset();
324 jint maxlen = p->maxlen - p->getOffset();
325 ssize_t retlen = 0;
327 if (timeout > 0)
329 // This implementation doesn't allow specifying an infinite
330 // timeout after specifying a finite one, but Sun's JDK 1.4.1
331 // didn't seem to allow this either....
332 int nRet= ::setsockopt(native_fd, SOL_SOCKET, SO_RCVTIMEO,
333 (char*)&timeout, sizeof(timeout));
334 if (nRet != NO_ERROR)
335 goto error;
338 retlen =
339 ::recvfrom (native_fd, (char *) dbytes, maxlen, 0, (sockaddr*) &u,
340 &addrlen);
341 if (retlen < 0)
342 goto error;
343 // FIXME: Deal with Multicast addressing and if the socket is connected.
344 jbyteArray raddr;
345 jint rport;
346 if (u.address.sin_family == AF_INET)
348 raddr = JvNewByteArray (4);
349 memcpy (elements (raddr), &u.address.sin_addr, 4);
350 rport = ntohs (u.address.sin_port);
352 #ifdef HAVE_INET6
353 else if (u.address.sin_family == AF_INET6)
355 raddr = JvNewByteArray (16);
356 memcpy (elements (raddr), &u.address6.sin6_addr, 16);
357 rport = ntohs (u.address6.sin6_port);
359 #endif
360 else
361 throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
363 p->setAddress (new ::java::net::InetAddress (raddr, NULL));
364 p->setPort (rport);
365 p->length = (jint) retlen;
366 return;
368 error:
369 DWORD dwErrorCode = WSAGetLastError();
370 if (dwErrorCode == WSAECONNRESET)
371 throw new ::java::net::PortUnreachableException (_Jv_WinStrError (dwErrorCode));
372 else if (dwErrorCode == WSAETIMEDOUT)
373 throw new ::java::net::SocketTimeoutException (_Jv_WinStrError (dwErrorCode));
374 else
375 throw new ::java::io::IOException (_Jv_WinStrError (dwErrorCode));
378 void
379 gnu::java::net::PlainDatagramSocketImpl::setTimeToLive (jint ttl)
381 // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4.
382 char val = (char) ttl;
383 socklen_t val_len = sizeof(val);
385 if (::setsockopt (native_fd, IPPROTO_IP, IP_MULTICAST_TTL, &val, val_len) == 0)
386 return;
388 _Jv_ThrowIOException ();
391 jint
392 gnu::java::net::PlainDatagramSocketImpl::getTimeToLive ()
394 // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4.
395 char val;
396 socklen_t val_len = sizeof(val);
398 if (::getsockopt (native_fd, IPPROTO_IP, IP_MULTICAST_TTL, &val, &val_len) == 0)
399 return ((int) val) & 0xFF;
401 _Jv_ThrowIOException ();
403 return -1;
404 // we should never get here
407 void
408 gnu::java::net::PlainDatagramSocketImpl::mcastGrp (::java::net::InetAddress *inetaddr,
409 ::java::net::NetworkInterface *,
410 jboolean join)
412 // FIXME: implement use of NetworkInterface
413 jbyteArray haddress = inetaddr->addr;
414 int len = haddress->length;
415 int level, opname;
416 const char *ptr;
417 if (0)
419 #if HAVE_STRUCT_IP_MREQ
420 else if (len == 4)
422 level = IPPROTO_IP;
423 opname = join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
424 memcpy (&u.mreq.imr_multiaddr, bytes, len);
425 // FIXME: If a non-default interface is set, use it; see Stevens p. 501.
426 // Maybe not, see note in last paragraph at bottom of Stevens p. 497.
427 u.mreq.imr_interface.s_addr = htonl (INADDR_ANY);
428 len = sizeof (struct ip_mreq);
429 ptr = (const char *) &u.mreq;
431 #endif
432 #if HAVE_STRUCT_IPV6_MREQ
433 else if (len == 16)
435 level = IPPROTO_IPV6;
437 /* Prefer new RFC 2553 names. */
438 #ifndef IPV6_JOIN_GROUP
439 #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
440 #endif
441 #ifndef IPV6_LEAVE_GROUP
442 #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
443 #endif
445 opname = join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP;
446 memcpy (&u.mreq6.ipv6mr_multiaddr, bytes, len);
447 // FIXME: If a non-default interface is set, use it; see Stevens p. 501.
448 // Maybe not, see note in last paragraph at bottom of Stevens p. 497.
449 u.mreq6.ipv6mr_interface = 0;
450 len = sizeof (struct ipv6_mreq);
451 ptr = (const char *) &u.mreq6;
453 #endif
454 else
455 throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
457 if (::setsockopt (native_fd, level, opname, ptr, len) == 0)
458 return;
460 _Jv_ThrowIOException ();
463 void
464 gnu::java::net::PlainDatagramSocketImpl::setOption (jint optID,
465 ::java::lang::Object *value)
467 int val;
468 socklen_t val_len = sizeof (val);
470 if (native_fd < 0)
471 throw new ::java::net::SocketException (JvNewStringUTF ("Socket closed"));
473 if (_Jv_IsInstanceOf (value, &::java::lang::Boolean::class$))
475 ::java::lang::Boolean *boolobj =
476 static_cast< ::java::lang::Boolean *> (value);
477 val = boolobj->booleanValue() ? 1 : 0;
479 else if (_Jv_IsInstanceOf (value, &::java::lang::Integer::class$))
481 ::java::lang::Integer *intobj =
482 static_cast< ::java::lang::Integer *> (value);
483 val = (int) intobj->intValue();
485 // Else assume value to be an InetAddress for use with IP_MULTICAST_IF.
487 switch (optID)
489 case _Jv_TCP_NODELAY_ :
490 throw new ::java::net::SocketException (
491 JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
492 return;
493 case _Jv_SO_LINGER_ :
494 throw new ::java::net::SocketException (
495 JvNewStringUTF ("SO_LINGER not valid for UDP"));
496 return;
497 case _Jv_SO_KEEPALIVE_ :
498 throw new ::java::net::SocketException (
499 JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
500 return;
502 case _Jv_SO_BROADCAST_ :
503 if (::setsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &val,
504 val_len) != 0)
505 goto error;
506 break;
508 case _Jv_SO_OOBINLINE_ :
509 throw new ::java::net::SocketException (
510 JvNewStringUTF ("SO_OOBINLINE: not valid for UDP"));
511 break;
513 case _Jv_SO_SNDBUF_ :
514 case _Jv_SO_RCVBUF_ :
515 int opt;
516 optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
517 if (::setsockopt (native_fd, SOL_SOCKET, opt, (char *) &val, val_len) != 0)
518 goto error;
519 return;
520 case _Jv_SO_REUSEADDR_ :
521 if (::setsockopt (native_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
522 val_len) != 0)
523 goto error;
524 return;
525 case _Jv_SO_BINDADDR_ :
526 throw new ::java::net::SocketException (
527 JvNewStringUTF ("SO_BINDADDR: read only option"));
528 return;
529 case _Jv_IP_MULTICAST_IF_ :
530 union InAddr u;
531 jbyteArray haddress;
532 jbyte *bytes;
533 int len;
534 int level, opname;
535 const char *ptr;
537 haddress = ((::java::net::InetAddress *) value)->addr;
538 bytes = elements (haddress);
539 len = haddress->length;
540 if (len == 4)
542 level = IPPROTO_IP;
543 opname = IP_MULTICAST_IF;
544 memcpy (&u.addr, bytes, len);
545 len = sizeof (struct in_addr);
546 ptr = (const char *) &u.addr;
548 // Tru64 UNIX V5.0 has struct sockaddr_in6, but no IPV6_MULTICAST_IF
549 #if defined (HAVE_INET6) && defined (IPV6_MULTICAST_IF)
550 else if (len == 16)
552 level = IPPROTO_IPV6;
553 opname = IPV6_MULTICAST_IF;
554 memcpy (&u.addr6, bytes, len);
555 len = sizeof (struct in6_addr);
556 ptr = (const char *) &u.addr6;
558 #endif
559 else
560 throw
561 new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
563 if (::setsockopt (native_fd, level, opname, ptr, len) != 0)
564 goto error;
565 return;
567 case _Jv_IP_MULTICAST_IF2_ :
568 throw new ::java::net::SocketException (
569 JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
570 break;
572 case _Jv_IP_MULTICAST_LOOP_ :
573 throw new ::java::net::SocketException (
574 JvNewStringUTF ("IP_MULTICAST_LOOP: not yet implemented"));
575 break;
577 case _Jv_IP_TOS_ :
578 if (::setsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val,
579 val_len) != 0)
580 goto error;
581 return;
583 case _Jv_SO_TIMEOUT_ :
584 timeout = val;
585 return;
586 default :
587 WSASetLastError (WSAENOPROTOOPT);
590 error:
591 _Jv_ThrowSocketException ();
594 ::java::lang::Object *
595 gnu::java::net::PlainDatagramSocketImpl::getOption (jint optID)
597 int val;
598 socklen_t val_len = sizeof(val);
599 union SockAddr u;
600 socklen_t addrlen = sizeof(u);
602 switch (optID)
604 case _Jv_TCP_NODELAY_ :
605 throw new ::java::net::SocketException (
606 JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
607 break;
608 case _Jv_SO_LINGER_ :
609 throw new ::java::net::SocketException (
610 JvNewStringUTF ("SO_LINGER not valid for UDP"));
611 break;
612 case _Jv_SO_KEEPALIVE_ :
613 throw new ::java::net::SocketException (
614 JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
615 break;
617 case _Jv_SO_BROADCAST_ :
618 if (::getsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &val,
619 &val_len) != 0)
620 goto error;
621 return new ::java::lang::Boolean (val != 0);
623 case _Jv_SO_OOBINLINE_ :
624 throw new ::java::net::SocketException (
625 JvNewStringUTF ("SO_OOBINLINE not valid for UDP"));
626 break;
628 case _Jv_SO_RCVBUF_ :
629 case _Jv_SO_SNDBUF_ :
630 int opt;
631 optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
632 if (::getsockopt (native_fd, SOL_SOCKET, opt, (char *) &val, &val_len) != 0)
633 goto error;
634 else
635 return new ::java::lang::Integer (val);
636 break;
637 case _Jv_SO_BINDADDR_:
638 // cache the local address
639 if (localAddress == NULL)
641 jbyteArray laddr;
642 if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) != 0)
643 goto error;
644 if (u.address.sin_family == AF_INET)
646 laddr = JvNewByteArray (4);
647 memcpy (elements (laddr), &u.address.sin_addr, 4);
649 #ifdef HAVE_INET6
650 else if (u.address.sin_family == AF_INET6)
652 laddr = JvNewByteArray (16);
653 memcpy (elements (laddr), &u.address6.sin6_addr, 16);
655 #endif
656 else
657 throw new ::java::net::SocketException (
658 JvNewStringUTF ("invalid family"));
659 localAddress = new ::java::net::InetAddress (laddr, NULL);
661 return localAddress;
662 break;
663 case _Jv_SO_REUSEADDR_ :
664 if (::getsockopt (native_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
665 &val_len) != 0)
666 goto error;
667 return new ::java::lang::Boolean (val != 0);
668 break;
669 case _Jv_IP_MULTICAST_IF_ :
670 struct in_addr inaddr;
671 socklen_t inaddr_len;
672 char *bytes;
674 inaddr_len = sizeof(inaddr);
675 if (::getsockopt (native_fd, IPPROTO_IP, IP_MULTICAST_IF, (char *) &inaddr,
676 &inaddr_len) != 0)
677 goto error;
679 bytes = inet_ntoa (inaddr);
681 return ::java::net::InetAddress::getByName (JvNewStringLatin1 (bytes));
682 break;
683 case _Jv_SO_TIMEOUT_ :
684 return new ::java::lang::Integer (timeout);
685 break;
687 case _Jv_IP_MULTICAST_IF2_ :
688 throw new ::java::net::SocketException (
689 JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
690 break;
692 case _Jv_IP_MULTICAST_LOOP_ :
693 if (::getsockopt (native_fd, SOL_SOCKET, IP_MULTICAST_LOOP, (char *) &val,
694 &val_len) != 0)
695 goto error;
696 return new ::java::lang::Boolean (val != 0);
698 case _Jv_IP_TOS_ :
699 if (::getsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val,
700 &val_len) != 0)
701 goto error;
702 return new ::java::lang::Integer (val);
704 default :
705 WSASetLastError (WSAENOPROTOOPT);
708 error:
709 _Jv_ThrowSocketException ();
710 return 0;
711 // we should never get here