OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [gnu/] [java/] [net/] [natPlainSocketImplWin32.cc] - Blame information for rev 843

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 756 jeremybenn
/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation
2
 
3
   This file is part of libgcj.
4
 
5
This software is copyrighted work licensed under the terms of the
6
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
7
details.  */
8
 
9
#include <config.h>
10
#include <platform.h>
11
 
12
#undef STRICT
13
#undef MAX_PRIORITY
14
#undef MIN_PRIORITY
15
 
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>
35
 
36
union SockAddr
37
{
38
  struct sockaddr_in address;
39
#ifdef HAVE_INET6
40
  struct sockaddr_in6 address6;
41
#endif
42
};
43
 
44
void
45
gnu::java::net::PlainSocketImpl::create (jboolean stream)
46
{
47
  SOCKET sock = ::socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
48
 
49
  if (sock == INVALID_SOCKET)
50
    {
51
      _Jv_ThrowIOException ();
52
    }
53
 
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);
58
 
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;
62
}
63
 
64
void
65
gnu::java::net::PlainSocketImpl::bind (::java::net::InetAddress *host, jint lport)
66
{
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;
72
 
73
  if (len == 4)
74
    {
75
      u.address.sin_family = AF_INET;
76
 
77
      if (host != NULL)
78
        memcpy (&u.address.sin_addr, bytes, len);
79
      else
80
        u.address.sin_addr.s_addr = htonl (INADDR_ANY);
81
 
82
      len = sizeof (struct sockaddr_in);
83
      u.address.sin_port = htons (lport);
84
    }
85
#ifdef HAVE_INET6
86
  else if (len == 16)
87
    {
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);
92
    }
93
#endif
94
  else
95
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
96
 
97
  if (::bind (native_fd, ptr, len) != SOCKET_ERROR)
98
    {
99
      socklen_t addrlen = sizeof(u);
100
 
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;
107
 
108
      return;
109
    }
110
 
111
error:
112
  DWORD dwErrorCode = WSAGetLastError ();
113
  throw new ::java::net::BindException (_Jv_WinStrError (dwErrorCode));
114
}
115
 
116
static void
117
throwConnectException (DWORD dwErrorCode)
118
{
119
  throw new ::java::net::ConnectException (_Jv_WinStrError (dwErrorCode));
120
}
121
 
122
static void
123
throwConnectException ()
124
{
125
  throwConnectException (WSAGetLastError ());
126
}
127
 
128
void
129
gnu::java::net::PlainSocketImpl::connect (::java::net::SocketAddress *addr,
130
                                     jint timeout)
131
{
132
  ::java::net::InetSocketAddress *tmp = (::java::net::InetSocketAddress*) addr;
133
  ::java::net::InetAddress *host = tmp->getAddress();
134
  jint rport = tmp->getPort();
135
 
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;
144
 
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;
151
 
152
  if (len == 4)
153
    {
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);
158
    }
159
#ifdef HAVE_INET6
160
  else if (len == 16)
161
    {
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);
166
    }
167
#endif
168
  else
169
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
170
 
171
  if (timeout > 0)
172
    {
173
      // FIXME: we're creating a fresh WSAEVENT for each connect().
174
      WSAEventWrapper aWSAEventWrapper(native_fd, FD_CONNECT);
175
      WSAEVENT hEvent = aWSAEventWrapper.getEventHandle ();
176
 
177
      if (::connect (native_fd, ptr, len) == SOCKET_ERROR)
178
      {
179
        if (WSAGetLastError () != WSAEWOULDBLOCK)
180
          throwConnectException ();
181
 
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
186
 
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();
191
 
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"));
197
 
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)
204
          {
205
            throwConnectException ();
206
          }
207
 
208
        if (nErrCode != NO_ERROR)
209
          {
210
            throwConnectException (nErrCode);
211
          }
212
      }
213
    }
214
  else
215
    {
216
      if (::connect (native_fd, ptr, len) == SOCKET_ERROR)
217
        throwConnectException();
218
    }
219
 
220
  // A bind may not have been done on this socket; if so, set localport now.
221
  if (localport == 0)
222
    {
223
      if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) != SOCKET_ERROR)
224
        localport = ntohs (u.address.sin_port);
225
      else
226
        throwConnectException();
227
    }
228
}
229
 
230
void
231
gnu::java::net::PlainSocketImpl::listen (jint backlog)
232
{
233
  if (::listen (native_fd, backlog) == SOCKET_ERROR)
234
    {
235
      _Jv_ThrowIOException ();
236
    }
237
}
238
 
239
void
240
gnu::java::net::PlainSocketImpl::accept (gnu::java::net::PlainSocketImpl *s)
241
{
242
  union SockAddr u;
243
  socklen_t addrlen = sizeof(u);
244
  HANDLE hSocket = 0;
245
  SOCKET new_socket = 0;
246
 
247
  if (timeout > 0)
248
    {
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 ();
255
 
256
      for (;;)
257
      {
258
        new_socket = ::accept (native_fd, (sockaddr*) &u, &addrlen);
259
 
260
        if (new_socket != INVALID_SOCKET)
261
        {
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
268
 
269
          unsigned long lSockOpt = 0L;
270
            // blocking mode
271
          if (ioctlsocket(new_socket, FIONBIO, &lSockOpt) == SOCKET_ERROR)
272
          {
273
            goto error;
274
          }
275
          break;
276
        }
277
        else if (WSAGetLastError () != WSAEWOULDBLOCK)
278
          {
279
            goto error;
280
          }
281
 
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
286
 
287
        // Reset and ignore our thread's interrupted flag.
288
        ::java::lang::Thread::interrupted();
289
 
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"));
295
      }
296
    }
297
  else
298
    {
299
      new_socket = ::accept (native_fd, (sockaddr*) &u, &addrlen);
300
    }
301
 
302
  if (new_socket == INVALID_SOCKET)
303
    goto error;
304
 
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);
309
 
310
  jbyteArray raddr;
311
  jint rport;
312
  if (u.address.sin_family == AF_INET)
313
    {
314
      raddr = JvNewByteArray (4);
315
      memcpy (elements (raddr), &u.address.sin_addr, 4);
316
      rport = ntohs (u.address.sin_port);
317
    }
318
#ifdef HAVE_INET6
319
  else if (u.address.sin_family == AF_INET6)
320
    {
321
      raddr = JvNewByteArray (16);
322
      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
323
      rport = ntohs (u.address6.sin6_port);
324
    }
325
#endif
326
  else
327
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
328
 
329
  s->native_fd = (jint) hSocket;
330
  s->localport = localport;
331
  s->address = ::java::net::InetAddress::getByAddress (raddr);
332
  s->port = rport;
333
  return;
334
 
335
 error:
336
  _Jv_ThrowIOException ();
337
}
338
 
339
// Close(shutdown) the socket.
340
void
341
gnu::java::net::PlainSocketImpl::close()
342
{
343
  // Avoid races from asynchronous finalization.
344
  JvSynchronize sync (this);
345
 
346
  // should we use shutdown here? how would that effect so_linger?
347
  int res = ::closesocket (native_fd);
348
 
349
  if (res == -1)
350
    {
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 ();
357
    }
358
  // Safe place to reset the file pointer.
359
  native_fd = -1;
360
  timeout = 0;
361
}
362
 
363
// Write a byte to the socket.
364
void
365
gnu::java::net::PlainSocketImpl$SocketOutputStream::write(jint b)
366
{
367
  jbyte d =(jbyte) b;
368
  int r = 0;
369
 
370
  while (r != 1)
371
    {
372
      r = ::send (this$0->native_fd, (char*) &d, 1, 0);
373
      if (r == -1)
374
        {
375
          DWORD dwErr = WSAGetLastError();
376
 
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();
381
 
382
          // Some errors should not cause exceptions.
383
          if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET
384
            && dwErr != WSAENOTSOCK)
385
            _Jv_ThrowIOException ();
386
          break;
387
        }
388
    }
389
}
390
 
391
// Write some bytes to the socket.
392
void
393
gnu::java::net::PlainSocketImpl$SocketOutputStream::write(jbyteArray b,
394
  jint offset, jint len)
395
{
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;
400
 
401
  jbyte *bytes = elements (b) + offset;
402
  int written = 0;
403
  while (len > 0)
404
    {
405
      int r = ::send (this$0->native_fd, (char*) bytes, len, 0);
406
 
407
      if (r == -1)
408
        {
409
          DWORD dwErr = WSAGetLastError();
410
 
411
          // Reset and ignore our thread's interrupted flag.
412
          ::java::lang::Thread::interrupted();
413
 
414
          // Some errors should not cause exceptions.
415
          if (dwErr != WSAENOTCONN && dwErr != WSAECONNRESET
416
            && dwErr != WSAENOTSOCK)
417
            _Jv_ThrowIOException ();
418
          break;
419
        }
420
 
421
      written += r;
422
      len -= r;
423
      bytes += r;
424
    }
425
}
426
 
427
void
428
gnu::java::net::PlainSocketImpl::sendUrgentData (jint)
429
{
430
  throw new ::java::net::SocketException (JvNewStringLatin1 (
431
    "PlainSocketImpl: sending of urgent data not supported by this socket"));
432
}
433
 
434
// read() helper
435
static jint
436
doRead(int native_fd, void* buf, int count, int timeout)
437
{
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().
443
 
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)
452
  {
453
    dwErrorCode = WSAGetLastError ();
454
    goto error;
455
  }
456
 
457
  r = ::recv (native_fd, (char*) buf, count, 0);
458
 
459
  if (r == 0)
460
    return -1;
461
 
462
  dwErrorCode = WSAGetLastError ();
463
    // save WSAGetLastError() before calling Thread.interrupted()
464
 
465
  // Reset and ignore our thread's interrupted flag.
466
  ::java::lang::Thread::interrupted();
467
 
468
  if (r == -1)
469
    {
470
error:
471
      // Some errors cause us to return end of stream...
472
      if (dwErrorCode == WSAENOTCONN)
473
        return -1;
474
 
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);
481
    }
482
 
483
   return r;
484
}
485
 
486
// Read a single byte from the socket.
487
jint
488
gnu::java::net::PlainSocketImpl$SocketInputStream::read(void)
489
{
490
  jbyte b;
491
  doRead(this$0->native_fd, &b, 1, this$0->timeout);
492
  return b & 0xFF;
493
}
494
 
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)
499
{
500
  // If zero bytes were requested, short circuit so that recv
501
  // doesn't signal EOF.
502
  if (count == 0)
503
    return 0;
504
 
505
  if (! buffer)
506
    throw new ::java::lang::NullPointerException;
507
 
508
  jsize bsize = JvGetArrayLength (buffer);
509
 
510
  if (offset < 0 || count < 0 || offset + count > bsize)
511
    throw new ::java::lang::ArrayIndexOutOfBoundsException;
512
 
513
  jbyte *bytes = elements (buffer) + offset;
514
 
515
  // Read the socket.
516
  return doRead(this$0->native_fd, bytes, count, this$0->timeout);
517
}
518
 
519
// How many bytes are available?
520
jint
521
gnu::java::net::PlainSocketImpl::available(void)
522
{
523
  unsigned long num = 0;
524
 
525
  if (::ioctlsocket (native_fd, FIONREAD, &num) == SOCKET_ERROR)
526
    _Jv_ThrowIOException ();
527
 
528
  return (jint) num;
529
}
530
 
531
void
532
gnu::java::net::PlainSocketImpl::setOption (jint optID, ::java::lang::Object *value)
533
{
534
  int val;
535
  socklen_t val_len = sizeof (val);
536
 
537
  if (native_fd < 0)
538
    throw new ::java::net::SocketException (JvNewStringUTF ("Socket closed"));
539
 
540
  if (_Jv_IsInstanceOf (value, &::java::lang::Boolean::class$))
541
    {
542
      ::java::lang::Boolean *boolobj =
543
        static_cast< ::java::lang::Boolean *> (value);
544
      if (boolobj->booleanValue())
545
        val = 1;
546
      else
547
        {
548
          if (optID == _Jv_SO_LINGER_)
549
            val = -1;
550
          else
551
            val = 0;
552
        }
553
    }
554
  else if (_Jv_IsInstanceOf (value, &::java::lang::Integer::class$))
555
    {
556
      ::java::lang::Integer *intobj =
557
        static_cast< ::java::lang::Integer *> (value);
558
      val = (int) intobj->intValue();
559
    }
560
  else
561
    {
562
      throw new ::java::lang::IllegalArgumentException (
563
        JvNewStringLatin1 ("`value' must be Boolean or Integer"));
564
    }
565
 
566
  switch (optID)
567
    {
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;
573
 
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;
579
 
580
      case _Jv_SO_BROADCAST_ :
581
        throw new ::java::net::SocketException
582
          (JvNewStringUTF ("SO_BROADCAST not valid for TCP"));
583
        break;
584
 
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;
590
 
591
      case _Jv_SO_LINGER_ :
592
        struct linger l_val;
593
        l_val.l_onoff = (val != -1);
594
        l_val.l_linger = val;
595
 
596
        if (::setsockopt (native_fd, SOL_SOCKET, SO_LINGER, (char *) &l_val,
597
                          sizeof(l_val)) == SOCKET_ERROR)
598
          goto error;
599
        return;
600
 
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;
609
 
610
      case _Jv_SO_BINDADDR_ :
611
        throw new ::java::net::SocketException (
612
          JvNewStringUTF ("SO_BINDADDR: read only option"));
613
        return;
614
 
615
      case _Jv_IP_MULTICAST_IF_ :
616
        throw new ::java::net::SocketException (
617
          JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP"));
618
        return;
619
 
620
      case _Jv_IP_MULTICAST_IF2_ :
621
        throw new ::java::net::SocketException (
622
          JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP"));
623
        break;
624
 
625
      case _Jv_IP_MULTICAST_LOOP_ :
626
        throw new ::java::net::SocketException (
627
          JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP"));
628
        break;
629
 
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;
635
 
636
      case _Jv_SO_REUSEADDR_ :
637
        throw new ::java::net::SocketException (
638
          JvNewStringUTF ("SO_REUSEADDR: not valid for TCP"));
639
        return;
640
 
641
      case _Jv_SO_TIMEOUT_ :
642
        timeout = val;
643
        return;
644
 
645
      default :
646
        WSASetLastError (WSAENOPROTOOPT);
647
    }
648
 
649
error:
650
  _Jv_ThrowSocketException ();
651
}
652
 
653
::java::lang::Object *
654
gnu::java::net::PlainSocketImpl::getOption (jint optID)
655
{
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);
662
 
663
  switch (optID)
664
    {
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;
672
 
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;
677
 
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;
683
 
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);
690
 
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);
696
 
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);
702
 
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)
716
        {
717
          jbyteArray laddr;
718
 
719
          if (::getsockname (native_fd, (sockaddr*) &u,
720
                             &addrlen) == SOCKET_ERROR)
721
            goto error;
722
 
723
          if (u.address.sin_family == AF_INET)
724
            {
725
              laddr = JvNewByteArray (4);
726
              memcpy (elements (laddr), &u.address.sin_addr, 4);
727
            }
728
#ifdef HAVE_INET6
729
          else if (u.address.sin_family == AF_INET6)
730
            {
731
              laddr = JvNewByteArray (16);
732
              memcpy (elements (laddr), &u.address6.sin6_addr, 16);
733
            }
734
#endif
735
          else
736
            throw new ::java::net::SocketException
737
              (JvNewStringUTF ("invalid family"));
738
          localAddress = ::java::net::InetAddress::getByAddress (laddr);
739
        }
740
 
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;
747
 
748
    case _Jv_IP_MULTICAST_IF2_ :
749
      throw new ::java::net::SocketException
750
        (JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP"));
751
      break;
752
 
753
    case _Jv_IP_MULTICAST_LOOP_ :
754
      throw new ::java::net::SocketException
755
        (JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP"));
756
      break;
757
 
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;
764
 
765
    case _Jv_SO_REUSEADDR_ :
766
      throw new ::java::net::SocketException
767
        (JvNewStringUTF ("SO_REUSEADDR: not valid for TCP"));
768
      break;
769
 
770
    case _Jv_SO_TIMEOUT_ :
771
      return new ::java::lang::Integer (timeout);
772
      break;
773
 
774
    default :
775
      WSASetLastError (WSAENOPROTOOPT);
776
    }
777
 
778
error:
779
  _Jv_ThrowSocketException ();
780
  return 0;
781
    // we should never get here
782
}
783
 
784
void
785
gnu::java::net::PlainSocketImpl::shutdownInput (void)
786
{
787
  if (::shutdown (native_fd, 0))
788
    _Jv_ThrowSocketException ();
789
}
790
 
791
void
792
gnu::java::net::PlainSocketImpl::shutdownOutput (void)
793
{
794
  if (::shutdown (native_fd, 1))
795
    _Jv_ThrowSocketException ();
796
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.