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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [native/] [jni/] [java-net/] [javanet.c] - Blame information for rev 774

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 774 jeremybenn
/* javanet.c - Common internal functions for the java.net package
2
   Copyright (C) 1998, 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
/* do not move; needed here because of some macro definitions */
39
#include <config.h>
40
 
41
#include <stdlib.h>
42
#include <stdio.h>
43
#include <string.h>
44
 
45
#include <jni.h>
46
#include <jcl.h>
47
 
48
#include "cpnative.h"
49
#include "cpnet.h"
50
 
51
#include "javanet.h"
52
 
53
#ifndef WITHOUT_NETWORK
54
/* Need to have some value for SO_TIMEOUT */
55
#ifndef SO_TIMEOUT
56
#ifndef SO_RCVTIMEO
57
#warning Neither SO_TIMEOUT or SO_RCVTIMEO are defined!
58
#warning This will cause all get/setOption calls with that value to throw an exception
59
#else
60
#define SO_TIMEOUT SO_RCVTIMEO
61
#endif /* not SO_RCVTIMEO */
62
#endif /* not SO_TIMEOUT */
63
#endif /* WITHOUT_NETWORK */
64
 
65
/*************************************************************************/
66
 
67
/*
68
 * Sets an integer field in the specified object.
69
 */
70
static void
71
_javanet_set_int_field (JNIEnv * env, jobject obj,
72
                        const char *class, const char *field, int val)
73
{
74
  jclass cls;
75
  jfieldID fid;
76
 
77
  cls = (*env)->FindClass (env, class);
78
  if (cls == NULL)
79
    return;
80
 
81
  fid = (*env)->GetFieldID (env, cls, field, "I");
82
  if (fid == NULL)
83
    return;
84
 
85
  (*env)->SetIntField (env, obj, fid, val);
86
 
87
  return;
88
}
89
 
90
/*************************************************************************/
91
 
92
/*
93
 * Returns the value of the specified integer instance variable field or
94
 * -1 if an error occurs.
95
 */
96
int
97
_javanet_get_int_field (JNIEnv * env, jobject obj, const char *field)
98
{
99
  jclass cls = 0;
100
  jfieldID fid;
101
  int fd;
102
 
103
  DBG ("_javanet_get_int_field(): Entered _javanet_get_int_field\n");
104
 
105
  cls = (*env)->GetObjectClass (env, obj);
106
  if (cls == NULL)
107
    return -1;
108
 
109
  fid = (*env)->GetFieldID (env, cls, field, "I");
110
  if (fid == NULL)
111
    return -1;
112
  DBG ("_javanet_get_int_field(): Found field id\n");
113
 
114
  fd = (*env)->GetIntField (env, obj, fid);
115
 
116
  return fd;
117
}
118
 
119
/*************************************************************************/
120
 
121
/*
122
 * Creates a FileDescriptor object in the parent class.  It is not used
123
 * by this implementation, but the docs list it as a variable, so we
124
 * need to include it.
125
 */
126
static void
127
_javanet_create_localfd (JNIEnv * env, jobject this, jboolean stream)
128
{
129
  jclass this_cls, fd_cls;
130
  jfieldID fid;
131
  jmethodID mid;
132
  jobject fd_obj;
133
 
134
  DBG ("_javanet_create_localfd(): Entered _javanet_create_localfd\n");
135
 
136
  /* Look up the fd field */
137
  if (stream)
138
    this_cls = (*env)->FindClass(env, "java/net/SocketImpl");
139
  else
140
    this_cls = (*env)->FindClass(env, "java/net/DatagramSocketImpl");
141
  if (this_cls == NULL)
142
    return;
143
 
144
  fid = (*env)->GetFieldID (env, this_cls, "fd", "Ljava/io/FileDescriptor;");
145
  if (fid == NULL)
146
    return;
147
 
148
  DBG ("_javanet_create_localfd(): Found fd variable\n");
149
 
150
  /* Create a FileDescriptor */
151
  fd_cls = (*env)->FindClass (env, "java/io/FileDescriptor");
152
  if (fd_cls == NULL)
153
    return;
154
 
155
  DBG ("_javanet_create_localfd(): Found FileDescriptor class\n");
156
 
157
  mid = (*env)->GetMethodID (env, fd_cls, "<init>", "()V");
158
  if (mid == NULL)
159
    return;
160
 
161
  DBG ("_javanet_create_localfd(): Found FileDescriptor constructor\n");
162
 
163
  fd_obj = (*env)->NewObject (env, fd_cls, mid);
164
  if (fd_obj == NULL)
165
    return;
166
 
167
  DBG ("_javanet_create_localfd(): Created FileDescriptor\n");
168
 
169
  /* Now set the pointer to the new FileDescriptor */
170
  (*env)->SetObjectField (env, this, fid, fd_obj);
171
  DBG ("_javanet_create_localfd(): Set fd field\n");
172
 
173
  return;
174
}
175
 
176
/*************************************************************************/
177
 
178
/*
179
 * Returns a Boolean object with the specfied value
180
 */
181
static jobject
182
_javanet_create_boolean (JNIEnv * env, jboolean val)
183
{
184
  jclass cls;
185
  jmethodID mid;
186
  jobject obj;
187
 
188
  cls = (*env)->FindClass (env, "java/lang/Boolean");
189
  if (cls == NULL)
190
    return NULL;
191
 
192
  mid = (*env)->GetMethodID (env, cls, "<init>", "(Z)V");
193
  if (mid == NULL)
194
    return NULL;
195
 
196
  obj = (*env)->NewObject (env, cls, mid, val);
197
  if (obj == NULL)
198
    return NULL;
199
 
200
  return obj;
201
}
202
 
203
/*************************************************************************/
204
 
205
/*
206
 * Returns an Integer object with the specfied value
207
 */
208
static jobject
209
_javanet_create_integer (JNIEnv * env, jint val)
210
{
211
  jclass cls;
212
  jmethodID mid;
213
  jobject obj;
214
 
215
  cls = (*env)->FindClass (env, "java/lang/Integer");
216
  if (cls == NULL)
217
    return NULL;
218
 
219
  mid = (*env)->GetMethodID (env, cls, "<init>", "(I)V");
220
  if (mid == NULL)
221
    return NULL;
222
 
223
  obj = (*env)->NewObject (env, cls, mid, val);
224
  if (obj == NULL)
225
    return NULL;
226
 
227
  return obj;
228
}
229
 
230
/*************************************************************************/
231
 
232
/*
233
 * Builds an InetAddress object from a 32 bit address in host byte order
234
 */
235
jobject
236
_javanet_create_inetaddress (JNIEnv * env, cpnet_address *netaddr)
237
{
238
#ifndef WITHOUT_NETWORK
239
  jbyte octets[4];
240
  char buf[64];
241
  jclass ia_cls;
242
  jmethodID mid;
243
  jstring ip_str;
244
  jobject ia;
245
 
246
  /* Build a string IP address */
247
  cpnet_IPV4AddressToBytes(netaddr, octets);
248
  sprintf (buf, "%d.%d.%d.%d", (int) (unsigned char)octets[0], (int)(unsigned char)octets[1], (int)(unsigned char)octets[2], (int)(unsigned char)octets[3]);
249
  DBG ("_javanet_create_inetaddress(): Created ip addr string\n");
250
 
251
  /* Get an InetAddress object for this IP */
252
  ia_cls = (*env)->FindClass (env, "java/net/InetAddress");
253
  if (ia_cls == NULL)
254
    {
255
      return NULL;
256
    }
257
 
258
  DBG ("_javanet_create_inetaddress(): Found InetAddress class\n");
259
 
260
  mid = (*env)->GetStaticMethodID (env, ia_cls, "getByName",
261
                                   "(Ljava/lang/String;)Ljava/net/InetAddress;");
262
  if (mid == NULL)
263
    {
264
      return NULL;
265
    }
266
 
267
  DBG ("_javanet_create_inetaddress(): Found getByName method\n");
268
 
269
  ip_str = (*env)->NewStringUTF (env, buf);
270
  if (ip_str == NULL)
271
    {
272
      return NULL;
273
    }
274
 
275
  ia = (*env)->CallStaticObjectMethod (env, ia_cls, mid, ip_str);
276
  if (ia == NULL)
277
    {
278
      return NULL;
279
    }
280
 
281
  DBG ("_javanet_create_inetaddress(): Called getByName method\n");
282
 
283
  return ia;
284
#else /* not WITHOUT_NETWORK */
285
  return NULL;
286
#endif /* not WITHOUT_NETWORK */
287
}
288
 
289
/*************************************************************************/
290
 
291
static void
292
_javanet_set_remhost_addr (JNIEnv * env, jobject this, jobject ia)
293
{
294
  jclass this_cls;
295
  jfieldID fid;
296
 
297
  /* Set the variable in the object */
298
  this_cls = (*env)->FindClass (env, "java/net/SocketImpl");
299
  if (this_cls == NULL)
300
    return;
301
 
302
  fid =
303
    (*env)->GetFieldID (env, this_cls, "address", "Ljava/net/InetAddress;");
304
  if (fid == NULL)
305
    return;
306
 
307
  DBG ("_javanet_set_remhost_addr(): Found address field\n");
308
 
309
  (*env)->SetObjectField (env, this, fid, ia);
310
  DBG ("_javanet_set_remhost_addr(): Set field\n");
311
}
312
 
313
/*
314
 * Set's the value of the "addr" field in PlainSocketImpl with a new
315
 * InetAddress for the specified addr
316
 */
317
static void
318
_javanet_set_remhost (JNIEnv * env, jobject this, cpnet_address *netaddr)
319
{
320
  jobject ia;
321
 
322
  DBG ("_javanet_set_remhost(): Entered _javanet_set_remhost\n");
323
 
324
  /* Get an InetAddress object */
325
  ia = _javanet_create_inetaddress (env, netaddr);
326
  if (ia == NULL)
327
    return;
328
 
329
  _javanet_set_remhost_addr (env, this, ia);
330
}
331
 
332
 
333
/*************************************************************************/
334
 
335
/*
336
 * Returns an Internet address for the passed in InetAddress object
337
 */
338
cpnet_address *
339
_javanet_get_ip_netaddr (JNIEnv * env, jobject addr)
340
{
341
#ifndef WITHOUT_NETWORK
342
  jclass cls = 0;
343
  jmethodID mid;
344
  jarray arr = 0;
345
  jbyte *octets;
346
  cpnet_address *netaddr;
347
  jint len;
348
 
349
  DBG ("_javanet_get_ip_netaddr(): Entered _javanet_get_ip_netaddr\n");
350
 
351
  if (addr == NULL)
352
    {
353
      JCL_ThrowException (env, "java/lang/NullPointerException",
354
                          "Null address");
355
      return 0;
356
    }
357
 
358
  /* Call the getAddress method on the object to retrieve the IP address */
359
  cls = (*env)->GetObjectClass (env, addr);
360
  if (cls == NULL)
361
    return 0;
362
 
363
  mid = (*env)->GetMethodID (env, cls, "getAddress", "()[B");
364
  if (mid == NULL)
365
    return 0;
366
 
367
  DBG ("_javanet_get_ip_netaddr(): Got getAddress method\n");
368
 
369
  arr = (*env)->CallObjectMethod (env, addr, mid);
370
  if (arr == NULL)
371
    return 0;
372
 
373
  DBG ("_javanet_get_ip_netaddr(): Got the address\n");
374
 
375
  /* Turn the IP address into a system cpnet address.
376
   * If the length is 4 then it is an IPV4 address, if it
377
   * is 16 then it is an IPV6 address else it is an InternError. */
378
  len = (*env)->GetArrayLength (env, arr);
379
  if (len != 4 && len != 16)
380
    {
381
      JCL_ThrowException (env, IO_EXCEPTION, "Internal Error");
382
      return 0;
383
    }
384
  DBG ("_javanet_get_ip_netaddr(): Length ok\n");
385
 
386
  octets = (*env)->GetByteArrayElements (env, arr, 0);
387
  if (octets == NULL)
388
    return 0;
389
 
390
  DBG ("_javanet_get_ip_netaddr(): Grabbed bytes\n");
391
 
392
  switch (len)
393
    {
394
    case 4:
395
      netaddr = cpnet_newIPV4Address(env);
396
      cpnet_bytesToIPV4Address(netaddr, octets);
397
      break;
398
#ifdef HAVE_INET6
399
    case 16:
400
      netaddr = cpnet_newIPV6Address(env);
401
      cpnet_bytesToIPV6Address(netaddr, octets);
402
      break;
403
#endif
404
    default:
405
      /* This should not happen as we have checked before.
406
       * But that way we shut the compiler warnings */
407
      JCL_ThrowException (env, IO_EXCEPTION, "Internal Error");
408
      return 0;
409
 
410
    }
411
 
412
  (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
413
  DBG ("_javanet_get_ip_netaddr(): Done getting addr\n");
414
 
415
  return netaddr;
416
#else /* not WITHOUT_NETWORK */
417
#endif /* not WITHOUT_NETWORK */
418
}
419
 
420
/*************************************************************************/
421
 
422
/*
423
 * Creates a new stream or datagram socket
424
 */
425
void
426
_javanet_create (JNIEnv * env, jobject this, jboolean stream)
427
{
428
#ifndef WITHOUT_NETWORK
429
  int fd;
430
  int result;
431
 
432
  if (stream)
433
    {
434
      /* create a stream socket */
435
      result = cpnet_openSocketStream(env, &fd, AF_INET);
436
      if (result != CPNATIVE_OK)
437
        {
438
          JCL_ThrowException (env, IO_EXCEPTION,
439
                              cpnative_getErrorString (result));
440
          return;
441
        }
442
    }
443
  else
444
    {
445
      /* create a datagram socket, set broadcast option */
446
      result = cpnet_openSocketDatagram (env, &fd, AF_INET);
447
      if (result != CPNATIVE_OK)
448
        {
449
          JCL_ThrowException (env, IO_EXCEPTION,
450
                              cpnative_getErrorString (result));
451
          return;
452
        }
453
      result = cpnet_setBroadcast(env, fd, 1);
454
      if (result != CPNATIVE_OK)
455
        {
456
          JCL_ThrowException (env, IO_EXCEPTION,
457
                              cpnative_getErrorString (result));
458
          return;
459
        }
460
    }
461
 
462
  if (stream)
463
    _javanet_set_int_field (env, this, "gnu/java/net/PlainSocketImpl",
464
                            "native_fd", fd);
465
  else
466
    _javanet_set_int_field (env, this, "gnu/java/net/PlainDatagramSocketImpl",
467
                            "native_fd", fd);
468
 
469
  if ((*env)->ExceptionOccurred (env))
470
    {
471
      /* Try to make sure we close the socket since close() won't work. */
472
      do
473
        {
474
          result = cpnet_close(env, fd);
475
          if (result != CPNATIVE_OK && result != CPNATIVE_EINTR)
476
            return;
477
        }
478
      while (result != CPNATIVE_OK);
479
      return;
480
    }
481
 
482
#else /* not WITHOUT_NETWORK */
483
#endif /* not WITHOUT_NETWORK */
484
}
485
 
486
/*************************************************************************/
487
 
488
/*
489
 * Close the socket.  Any underlying streams will be closed by this
490
 * action as well.
491
 */
492
void
493
_javanet_close (JNIEnv * env, jobject this, int stream)
494
{
495
#ifndef WITHOUT_NETWORK
496
  int fd;
497
  int result;
498
  int error = 0;
499
 
500
  fd = _javanet_get_int_field (env, this, "native_fd");
501
  if (fd == -1)
502
    return;
503
 
504
  if (stream)
505
    _javanet_set_int_field (env, this, "gnu/java/net/PlainSocketImpl",
506
                            "native_fd", -1);
507
  else
508
    _javanet_set_int_field (env, this, "gnu/java/net/PlainDatagramSocketImpl",
509
                            "native_fd", -1);
510
  do
511
    {
512
      result = cpnet_close (env, fd);
513
      if (result != CPNATIVE_OK)
514
        {
515
          /* Only throw an error when a "real" error occurs. */
516
          if (result != CPNATIVE_EINTR && result != ENOTCONN && result != ECONNRESET && result != EBADF)
517
            JCL_ThrowException (env, IO_EXCEPTION,
518
                                cpnative_getErrorString (result));
519
        }
520
    }
521
  while (error == CPNATIVE_EINTR);
522
 
523
#else /* not WITHOUT_NETWORK */
524
#endif /* not WITHOUT_NETWORK */
525
}
526
 
527
/*************************************************************************/
528
 
529
/*
530
 * Connects to the specified destination.
531
 */
532
void
533
_javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port,
534
                  jboolean stream)
535
{
536
#ifndef WITHOUT_NETWORK
537
  cpnet_address *netaddr;
538
  int fd;
539
  int result;
540
  cpnet_address *local_addr;
541
  cpnet_address *remote_addr;
542
 
543
  DBG ("_javanet_connect(): Entered _javanet_connect\n");
544
 
545
  /* Pre-process input variables */
546
  netaddr = _javanet_get_ip_netaddr (env, addr);
547
  if ((*env)->ExceptionOccurred (env))
548
    return;
549
 
550
  if (port == -1)
551
    port = 0;
552
 
553
  cpnet_addressSetPort(netaddr, port);
554
 
555
  DBG ("_javanet_connect(): Got network address\n");
556
 
557
  /* Grab the real socket file descriptor */
558
  fd = _javanet_get_int_field (env, this, "native_fd");
559
  if (fd == -1)
560
    {
561
      JCL_ThrowException (env, IO_EXCEPTION,
562
                          "Internal error: _javanet_connect(): no native file descriptor");
563
      return;
564
    }
565
  DBG ("_javanet_connect(): Got native fd\n");
566
 
567
  /* Connect up */
568
  do
569
    {
570
      result = cpnet_connect (env, fd, netaddr);
571
      if (result != CPNATIVE_OK && result != CPNATIVE_EINTR)
572
        {
573
          JCL_ThrowException (env, CONNECT_EXCEPTION,
574
                              cpnative_getErrorString (result));
575
          return;
576
        }
577
    }
578
  while (result != CPNATIVE_OK);
579
 
580
  DBG ("_javanet_connect(): Connected successfully\n");
581
 
582
  /* Populate instance variables */
583
  result = cpnet_getLocalAddr (env, fd, &local_addr);
584
  if (result != CPNATIVE_OK)
585
    {
586
      cpnet_freeAddress(env, netaddr);
587
      JCL_ThrowException (env, IO_EXCEPTION,
588
                          cpnative_getErrorString (result));
589
      /* We don't care whether this succeeds. close() will cleanup later. */
590
      cpnet_close (env, fd);
591
      return;
592
    }
593
 
594
  _javanet_create_localfd (env, this, stream);
595
  if ((*env)->ExceptionOccurred (env))
596
    {
597
      /* We don't care whether this succeeds. close() will cleanup later. */
598
      cpnet_freeAddress(env, netaddr);
599
      cpnet_freeAddress(env, local_addr);
600
      cpnet_close (env, fd);
601
      return;
602
    }
603
  DBG ("_javanet_connect(): Created fd\n");
604
 
605
  if (stream)
606
    _javanet_set_int_field (env, this, "java/net/SocketImpl", "localport",
607
                            cpnet_addressGetPort(local_addr));
608
  else
609
    _javanet_set_int_field (env, this, "java/net/DatagramSocketImpl",
610
                            "localPort", cpnet_addressGetPort(local_addr));
611
 
612
  cpnet_freeAddress (env, local_addr);
613
  if ((*env)->ExceptionOccurred (env))
614
    {
615
      /* We don't care whether this succeeds. close() will cleanup later. */
616
      cpnet_freeAddress(env, netaddr);
617
      cpnet_close (env, fd);
618
      return;
619
    }
620
  DBG ("_javanet_connect(): Set the local port\n");
621
 
622
  result = cpnet_getRemoteAddr (env, fd, &remote_addr);
623
  if (result != CPNATIVE_OK)
624
    {
625
      cpnet_freeAddress(env, netaddr);
626
      JCL_ThrowException (env, IO_EXCEPTION,
627
                          cpnative_getErrorString (result));
628
      /* We don't care whether this succeeds. close() will cleanup later. */
629
      cpnet_close (env, fd);
630
      return;
631
    }
632
 
633
  if (stream)
634
    {
635
      if (cpnet_isAddressEqual(remote_addr, netaddr))
636
        {
637
          _javanet_set_remhost_addr (env, this, addr);
638
        }
639
      else
640
        {
641
          _javanet_set_remhost (env, this, remote_addr);
642
        }
643
      cpnet_freeAddress(env, netaddr);
644
 
645
      if ((*env)->ExceptionOccurred (env))
646
        {
647
          /* We don't care whether this succeeds. close() will cleanup later.
648
           */
649
          cpnet_freeAddress (env, remote_addr);
650
          cpnet_close (env, fd);
651
          return;
652
        }
653
      DBG ("_javanet_connect(): Set the remote host\n");
654
 
655
      _javanet_set_int_field (env, this, "java/net/SocketImpl", "port",
656
                              cpnet_addressGetPort(remote_addr));
657
      cpnet_freeAddress (env, remote_addr);
658
 
659
      if ((*env)->ExceptionOccurred (env))
660
        {
661
          /* We don't care whether this succeeds. close() will cleanup later.
662
           */
663
          cpnet_close (env, fd);
664
          return;
665
        }
666
      DBG ("_javanet_connect(): Set the remote port\n");
667
    }
668
#else /* not WITHOUT_NETWORK */
669
#endif /* not WITHOUT_NETWORK */
670
}
671
 
672
/*************************************************************************/
673
 
674
/*
675
 * This method binds the specified address to the specified local port.
676
 * Note that we have to set the local address and local
677
 * port public instance variables.
678
 */
679
void
680
_javanet_bind (JNIEnv * env, jobject this, jobject addr, jint port,
681
               int stream)
682
{
683
#ifndef WITHOUT_NETWORK
684
  jint fd;
685
  cpnet_address *tmpaddr;
686
  cpnet_address *local_addr;
687
  int result;
688
 
689
  DBG ("_javanet_bind(): Entering native bind()\n");
690
 
691
 /* Grab the real socket file descriptor */
692
  fd = _javanet_get_int_field (env, this, "native_fd");
693
  if (fd == -1)
694
    {
695
      JCL_ThrowException (env, IO_EXCEPTION,
696
                          "Internal error: _javanet_connect(): no native file descriptor");
697
      return;
698
    }
699
 
700
  cpnet_setReuseAddress (env, fd, 1);
701
 
702
  /* Get the address to connect to */
703
  tmpaddr = _javanet_get_ip_netaddr (env, addr);
704
  if ((*env)->ExceptionOccurred (env))
705
    return;
706
 
707
  cpnet_addressSetPort (tmpaddr, port);
708
  result = cpnet_bind(env, fd, tmpaddr);
709
  cpnet_freeAddress (env, tmpaddr);
710
  if (result != CPNATIVE_OK)
711
    {
712
      JCL_ThrowException (env, BIND_EXCEPTION,
713
                          cpnative_getErrorString (result));
714
      return;
715
    }
716
  DBG ("_javanet_bind(): Past bind\n");
717
 
718
  /* Update instance variables, specifically the local port number */
719
  result = cpnet_getLocalAddr (env, fd, &local_addr);
720
  if (result != CPNATIVE_OK)
721
    {
722
      JCL_ThrowException (env, IO_EXCEPTION,
723
                          cpnative_getErrorString (result));
724
      return;
725
    }
726
 
727
  if (stream)
728
    _javanet_set_int_field (env, this, "java/net/SocketImpl",
729
                            "localport", cpnet_addressGetPort (local_addr));
730
  else
731
    _javanet_set_int_field (env, this, "java/net/DatagramSocketImpl",
732
                            "localPort", cpnet_addressGetPort (local_addr));
733
  DBG ("_javanet_bind(): Past update port number\n");
734
 
735
  cpnet_freeAddress (env, local_addr);
736
 
737
  return;
738
#else /* not WITHOUT_NETWORK */
739
#endif /* not WITHOUT_NETWORK */
740
}
741
 
742
/*************************************************************************/
743
 
744
/*
745
 * Starts listening on a socket with the specified number of pending
746
 * connections allowed.
747
 */
748
void
749
_javanet_listen (JNIEnv * env, jobject this, jint queuelen)
750
{
751
#ifndef WITHOUT_NETWORK
752
  int fd;
753
  int result;
754
 
755
  /* Get the real file descriptor */
756
  fd = _javanet_get_int_field (env, this, "native_fd");
757
  if (fd == -1)
758
    {
759
      JCL_ThrowException (env, IO_EXCEPTION,
760
                          "Internal error: _javanet_listen(): no native file descriptor");
761
      return;
762
    }
763
 
764
  /* Start listening */
765
  result = cpnet_listen (env, fd, queuelen);
766
  if (result != CPNATIVE_OK)
767
    {
768
      JCL_ThrowException (env, IO_EXCEPTION,
769
                          cpnative_getErrorString (result));
770
      return;
771
    }
772
#else /* not WITHOUT_NETWORK */
773
#endif /* not WITHOUT_NETWORK */
774
}
775
 
776
/*************************************************************************/
777
 
778
/*
779
 * Accepts a new connection and assigns it to the passed in SocketImpl
780
 * object. Note that we assume this is a PlainSocketImpl just like us
781
 */
782
void
783
_javanet_accept (JNIEnv * env, jobject this, jobject impl)
784
{
785
#ifndef WITHOUT_NETWORK
786
  int fd, newfd;
787
  int result;
788
  cpnet_address *remote_addr, *local_addr;
789
 
790
  /* Get the real file descriptor */
791
  fd = _javanet_get_int_field (env, this, "native_fd");
792
  if (fd == -1)
793
    {
794
      JCL_ThrowException (env, IO_EXCEPTION,
795
                          "Internal error: _javanet_accept(): no native file descriptor");
796
      return;
797
    }
798
 
799
  /* Accept the connection */
800
  do
801
    {
802
      result = cpnet_accept (env, fd, &newfd);
803
      if (result != CPNATIVE_OK && result != CPNATIVE_EINTR)
804
        {
805
          if (result == ETIMEDOUT || result == EAGAIN)
806
            JCL_ThrowException (env, "java/net/SocketTimeoutException",
807
                                "Accept operation timed out");
808
          else
809
            JCL_ThrowException (env, IO_EXCEPTION,
810
                                cpnative_getErrorString (result));
811
          return;
812
        }
813
    }
814
  while (result != CPNATIVE_OK);
815
 
816
  /* Reset the inherited timeout. */
817
  cpnet_setSocketTimeout (env, newfd, 0);
818
 
819
  /* Populate instance variables */
820
  _javanet_set_int_field (env, impl, "gnu/java/net/PlainSocketImpl",
821
                          "native_fd", newfd);
822
 
823
  if ((*env)->ExceptionOccurred (env))
824
    {
825
      /* Try to make sure we close the socket since close() won't work. */
826
      do
827
        {
828
          result = cpnet_close (env, newfd);
829
          if (result != CPNATIVE_OK && result != CPNATIVE_EINTR)
830
            return;
831
        }
832
      while (result != CPNATIVE_OK);
833
      return;
834
    }
835
 
836
  result = cpnet_getLocalAddr (env, newfd, &local_addr);
837
  if (result != CPNATIVE_OK)
838
    {
839
      /* We don't care whether this succeeds. close() will cleanup later. */
840
      cpnet_close (env, newfd);
841
      JCL_ThrowException (env, IO_EXCEPTION,
842
                          cpnative_getErrorString (result));
843
      return;
844
    }
845
 
846
  _javanet_create_localfd (env, impl, 1);
847
  if ((*env)->ExceptionOccurred (env))
848
    {
849
      /* We don't care whether this succeeds. close() will cleanup later. */
850
      cpnet_freeAddress (env, local_addr);
851
      cpnet_close (env, newfd);
852
      return;
853
    }
854
 
855
  _javanet_set_int_field (env, impl, "java/net/SocketImpl", "localport",
856
                          cpnet_addressGetPort (local_addr));
857
  cpnet_freeAddress (env, local_addr);
858
  if ((*env)->ExceptionOccurred (env))
859
    {
860
      /* We don't care whether this succeeds. close() will cleanup later. */
861
      cpnet_close (env, newfd);
862
      return;
863
    }
864
 
865
  result = cpnet_getRemoteAddr (env, newfd, &remote_addr);
866
  if (result != CPNATIVE_OK)
867
    {
868
      JCL_ThrowException (env, IO_EXCEPTION,
869
                          cpnative_getErrorString (result));
870
      /* We don't care whether this succeeds. close() will cleanup later. */
871
      cpnet_close (env, newfd);
872
      return;
873
    }
874
 
875
  _javanet_set_remhost (env, impl, remote_addr);
876
  if ((*env)->ExceptionOccurred (env))
877
    {
878
      /* We don't care whether this succeeds. close() will cleanup later. */
879
      cpnet_close (env, newfd);
880
      cpnet_freeAddress (env, remote_addr);
881
      return;
882
    }
883
 
884
  _javanet_set_int_field (env, impl, "java/net/SocketImpl", "port",
885
                          cpnet_addressGetPort (remote_addr));
886
  cpnet_freeAddress (env, remote_addr);
887
  if ((*env)->ExceptionOccurred (env))
888
    {
889
      /* We don't care whether this succeeds. close() will cleanup later. */
890
      cpnet_close (env, newfd);
891
      return;
892
    }
893
#else /* not WITHOUT_NETWORK */
894
#endif /* not WITHOUT_NETWORK */
895
}
896
 
897
/*************************************************************************/
898
 
899
/*
900
 * Receives a buffer from a remote host. The args are:
901
 *
902
 * buf - The byte array into which the data received will be written
903
 * offset - Offset into the byte array to start writing
904
 * len - The number of bytes to read.
905
 * addr - Pointer to 32 bit net address of host to receive from. If null,
906
 *        this parm is ignored.  If pointing to an address of 0, the
907
 *        actual address read is stored here
908
 * port - Pointer to the port to receive from. If null, this parm is ignored.
909
 *        If it is 0, the actual remote port received from is stored here
910
 *
911
 * The actual number of bytes read is returned.
912
 */
913
int
914
_javanet_recvfrom (JNIEnv * env, jobject this, jarray buf, int offset,
915
                   int len, cpnet_address **addr)
916
{
917
#ifndef WITHOUT_NETWORK
918
  int fd;
919
  jbyte *p;
920
  cpnet_address *from_addr;
921
  jint received_bytes;
922
  int result;
923
 
924
  DBG ("_javanet_recvfrom(): Entered _javanet_recvfrom\n");
925
 
926
  /* Get the real file descriptor */
927
  fd = _javanet_get_int_field (env, this, "native_fd");
928
  if (fd == -1)
929
    {
930
      JCL_ThrowException (env, IO_EXCEPTION,
931
                          "Internal error: _javanet_recvfrom(): no native file descriptor");
932
      return 0;
933
    }
934
  DBG ("_javanet_recvfrom(): Got native_fd\n");
935
 
936
  /* Get a pointer to the buffer */
937
  p = (*env)->GetByteArrayElements (env, buf, 0);
938
  if (p == NULL)
939
    return 0;
940
 
941
  DBG ("_javanet_recvfrom(): Got buffer\n");
942
 
943
  /* Read the data */
944
  from_addr = NULL;
945
  do
946
    {
947
      if (addr != NULL)
948
        {
949
          result = cpnet_recvFrom (env, fd, p + offset, len, &from_addr, &received_bytes);
950
        }
951
      else
952
        {
953
          result = cpnet_recv (env, fd, p + offset, len, &received_bytes);
954
        }
955
    }
956
  while (result == CPNATIVE_EINTR);
957
  if (result != 0)
958
    {
959
      if (result == EAGAIN || result == ETIMEDOUT)
960
        JCL_ThrowException (env, "java/net/SocketTimeoutException", "Receive operation timed out");
961
      else
962
        JCL_ThrowException (env, IO_EXCEPTION,
963
                            cpnative_getErrorString (result));
964
 
965
      /* Cleanup and return. */
966
      (*env)->ReleaseByteArrayElements (env, buf, p, 0);
967
      return 0;
968
    }
969
 
970
  (*env)->ReleaseByteArrayElements (env, buf, p, 0);
971
 
972
  /* Handle return addr case */
973
  if (addr != NULL)
974
    {
975
      (*addr) = from_addr;
976
    }
977
 
978
  /* zero bytes received means recv() noticed the other side orderly
979
     closing the connection. */
980
  if (received_bytes == 0)
981
    received_bytes = -1;
982
 
983
  return received_bytes;
984
#else /* not WITHOUT_NETWORK */
985
#endif /* not WITHOUT_NETWORK */
986
}
987
 
988
/*************************************************************************/
989
 
990
/*
991
 * Sends a buffer to a remote host.  The args are:
992
 *
993
 * buf - A byte array
994
 * offset - Index into the byte array to start sendign
995
 * len - The number of bytes to write
996
 * addr - The 32bit address to send to (may be 0)
997
 * port - The port number to send to (may be 0)
998
 */
999
void
1000
_javanet_sendto (JNIEnv * env, jobject this, jarray buf, int offset, int len,
1001
                 cpnet_address *addr)
1002
{
1003
#ifndef WITHOUT_NETWORK
1004
  int fd;
1005
  jbyte *p;
1006
  jint bytes_sent;
1007
  int result;
1008
 
1009
  /* Get the real file descriptor */
1010
  fd = _javanet_get_int_field (env, this, "native_fd");
1011
  if (fd == -1)
1012
    {
1013
      JCL_ThrowException (env, IO_EXCEPTION,
1014
                          "Internal error: _javanet_sendto(): no native file descriptor");
1015
      return;
1016
    }
1017
 
1018
  /* Get a pointer to the buffer */
1019
  p = (*env)->GetByteArrayElements (env, buf, 0);
1020
  if (p == NULL)
1021
    return;
1022
 
1023
  /* We must send all the data, so repeat till done. */
1024
  while (len > 0)
1025
    {
1026
      /* Send the data */
1027
      if (addr == NULL)
1028
        {
1029
          DBG ("_javanet_sendto(): Sending....\n");
1030
          result = cpnet_send (env, fd, p + offset, len, &bytes_sent);
1031
        }
1032
      else
1033
        {
1034
          DBG ("_javanet_sendto(): Sending....\n");
1035
          result = cpnet_sendTo (env, fd, p + offset, len, addr, &bytes_sent);
1036
        }
1037
 
1038
      if (result == EDESTADDRREQ)
1039
        {
1040
          JCL_ThrowException (env, NULL_EXCEPTION,
1041
                              "Socket is not connected and no address is given");
1042
          break;
1043
        }
1044
 
1045
      if (bytes_sent < 0)
1046
        {
1047
          if (result != CPNATIVE_EINTR)
1048
            {
1049
              JCL_ThrowException (env, IO_EXCEPTION,
1050
                                  cpnative_getErrorString (result));
1051
              break;
1052
            }
1053
        }
1054
      else
1055
        {
1056
          len -= bytes_sent;
1057
          addr += bytes_sent;
1058
        }
1059
    }
1060
 
1061
  (*env)->ReleaseByteArrayElements (env, buf, p, 0);
1062
 
1063
#else /* not WITHOUT_NETWORK */
1064
#endif /* not WITHOUT_NETWORK */
1065
}
1066
 
1067
/*************************************************************************/
1068
 
1069
/*
1070
 * Sets the specified option for a socket
1071
 */
1072
void
1073
_javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
1074
{
1075
#ifndef WITHOUT_NETWORK
1076
  int fd;
1077
  int optval;
1078
  jclass cls;
1079
  jmethodID mid;
1080
  cpnet_address * address;
1081
  int result = CPNATIVE_OK;
1082
 
1083
  /* Get the real file descriptor */
1084
  fd = _javanet_get_int_field (env, this, "native_fd");
1085
  if (fd == -1)
1086
    {
1087
      JCL_ThrowException (env, IO_EXCEPTION,
1088
                          "Internal error: _javanet_set_option(): no native file descriptor");
1089
      return;
1090
    }
1091
 
1092
  /* We need a class object for all cases below */
1093
  cls = (*env)->GetObjectClass (env, val);
1094
  if (cls == NULL)
1095
    return;
1096
 
1097
  /* Process the option request */
1098
  switch (option_id)
1099
    {
1100
      /* TCP_NODELAY case.  val is a Boolean that tells us what to do */
1101
    case SOCKOPT_TCP_NODELAY:
1102
      mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
1103
      if (mid == NULL)
1104
        {
1105
          JCL_ThrowException (env, IO_EXCEPTION,
1106
                              "Internal error: _javanet_set_option()");
1107
          return;
1108
        }
1109
 
1110
      /* Should be a 0 or a 1 */
1111
      optval = (*env)->CallBooleanMethod (env, val, mid);
1112
      if ((*env)->ExceptionOccurred (env))
1113
        return;
1114
 
1115
      result = cpnet_setSocketTCPNoDelay (env, fd, optval);
1116
      break;
1117
 
1118
      /* SO_LINGER case.  If val is a boolean, then it will always be set
1119
         to false indicating disable linger, otherwise it will be an
1120
         integer that contains the linger value */
1121
    case SOCKOPT_SO_LINGER:
1122
      mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
1123
      if (mid)
1124
        {
1125
          /* We are disabling linger */
1126
          result = cpnet_setLinger (env, fd, JNI_FALSE, 0);
1127
        }
1128
      else
1129
        {
1130
          /* Clear exception if thrown for failure to do method lookup
1131
             above */
1132
          if ((*env)->ExceptionOccurred (env))
1133
            (*env)->ExceptionClear (env);
1134
 
1135
          mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
1136
          if (mid == NULL)
1137
            {
1138
              JCL_ThrowException (env, IO_EXCEPTION,
1139
                                  "Internal error: _javanet_set_option()");
1140
              return;
1141
            }
1142
 
1143
          optval = (*env)->CallIntMethod (env, val, mid);
1144
          if ((*env)->ExceptionOccurred (env))
1145
            return;
1146
 
1147
          result = cpnet_setLinger(env, fd, JNI_TRUE, optval);
1148
        }
1149
      break;
1150
 
1151
      /* SO_TIMEOUT case. Val will be an integer with the new value */
1152
      /* Not writable on Linux */
1153
    case SOCKOPT_SO_TIMEOUT:
1154
      mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
1155
      if (mid == NULL)
1156
        {
1157
          JCL_ThrowException (env, IO_EXCEPTION,
1158
                              "Internal error: _javanet_set_option()");
1159
          return;
1160
        }
1161
 
1162
      optval = (*env)->CallIntMethod (env, val, mid);
1163
      if ((*env)->ExceptionOccurred (env))
1164
        return;
1165
 
1166
      result = cpnet_setSocketTimeout (env, fd, optval);
1167
      break;
1168
 
1169
    case SOCKOPT_SO_SNDBUF:
1170
    case SOCKOPT_SO_RCVBUF:
1171
      mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
1172
      if (mid == NULL)
1173
        {
1174
          JCL_ThrowException (env, IO_EXCEPTION,
1175
                              "Internal error: _javanet_set_option()");
1176
          return;
1177
        }
1178
 
1179
 
1180
      optval = (*env)->CallIntMethod (env, val, mid);
1181
      if ((*env)->ExceptionOccurred (env))
1182
        return;
1183
 
1184
      if (option_id == SOCKOPT_SO_SNDBUF)
1185
        result = cpnet_setSendBuf (env, fd, optval);
1186
      else
1187
        result = cpnet_setRecvBuf (env, fd, optval);
1188
      break;
1189
 
1190
      /* TTL case.  Val with be an Integer with the new time to live value */
1191
    case SOCKOPT_IP_TTL:
1192
      mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
1193
      if (!mid)
1194
        {
1195
          JCL_ThrowException (env, IO_EXCEPTION,
1196
                              "Internal error: _javanet_set_option()");
1197
          return;
1198
        }
1199
 
1200
      optval = (*env)->CallIntMethod (env, val, mid);
1201
      if ((*env)->ExceptionOccurred (env))
1202
        return;
1203
 
1204
      result = cpnet_setTTL (env, fd, optval);
1205
      break;
1206
 
1207
      /* Multicast Interface case - val is InetAddress object */
1208
    case SOCKOPT_IP_MULTICAST_IF:
1209
      address = _javanet_get_ip_netaddr (env, val);
1210
 
1211
      if ((*env)->ExceptionOccurred (env))
1212
        return;
1213
 
1214
      result = cpnet_setMulticastIF (env, fd, address);
1215
      cpnet_freeAddress (env, address);
1216
      break;
1217
 
1218
    case SOCKOPT_SO_REUSEADDR:
1219
      mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
1220
      if (mid == NULL)
1221
        {
1222
          JCL_ThrowException (env, IO_EXCEPTION,
1223
                              "Internal error: _javanet_set_option()");
1224
          return;
1225
        }
1226
 
1227
      /* Should be a 0 or a 1 */
1228
      optval = (*env)->CallBooleanMethod (env, val, mid);
1229
      if ((*env)->ExceptionOccurred (env))
1230
        return;
1231
 
1232
      result = cpnet_setReuseAddress (env, fd, optval);
1233
      break;
1234
 
1235
    case SOCKOPT_SO_KEEPALIVE:
1236
      mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
1237
      if (mid == NULL)
1238
        {
1239
          JCL_ThrowException (env, IO_EXCEPTION,
1240
                              "Internal error: _javanet_set_option()");
1241
          return;
1242
        }
1243
 
1244
      /* Should be a 0 or a 1 */
1245
      optval = (*env)->CallBooleanMethod (env, val, mid);
1246
      if ((*env)->ExceptionOccurred (env))
1247
        return;
1248
 
1249
      result = cpnet_setKeepAlive (env, fd, optval);
1250
      break;
1251
 
1252
    case SOCKOPT_SO_BINDADDR:
1253
      JCL_ThrowException (env, SOCKET_EXCEPTION, "This option cannot be set");
1254
      break;
1255
 
1256
    default:
1257
      JCL_ThrowException (env, SOCKET_EXCEPTION, "Unrecognized option");
1258
      return;
1259
    }
1260
 
1261
  /* Check to see if above operations succeeded */
1262
  if (result != CPNATIVE_OK)
1263
    {
1264
      JCL_ThrowException (env, SOCKET_EXCEPTION,
1265
                          cpnative_getErrorString (result));
1266
      return;
1267
    }
1268
#else /* not WITHOUT_NETWORK */
1269
#endif /* not WITHOUT_NETWORK */
1270
}
1271
 
1272
/*************************************************************************/
1273
 
1274
/*
1275
 * Retrieves the specified option values for a socket
1276
 */
1277
jobject
1278
_javanet_get_option (JNIEnv * env, jobject this, jint option_id)
1279
{
1280
#ifndef WITHOUT_NETWORK
1281
  int fd;
1282
  int flag, optval;
1283
  cpnet_address *address;
1284
  int result;
1285
  jobject obj;
1286
 
1287
  /* Get the real file descriptor */
1288
  fd = _javanet_get_int_field (env, this, "native_fd");
1289
  if (fd == -1)
1290
    {
1291
      JCL_ThrowException (env, SOCKET_EXCEPTION,
1292
                          "Internal error: _javanet_get_option(): no native file descriptor");
1293
      return (0);
1294
    }
1295
 
1296
  /* Process the option requested */
1297
  switch (option_id)
1298
    {
1299
      /* TCP_NODELAY case.  Return a Boolean indicating on or off */
1300
    case SOCKOPT_TCP_NODELAY:
1301
      result = cpnet_getSocketTCPNoDelay (env, fd, &optval);
1302
      if (result != CPNATIVE_OK)
1303
        {
1304
          JCL_ThrowException (env, SOCKET_EXCEPTION,
1305
                              cpnative_getErrorString (result));
1306
          return (0);
1307
        }
1308
 
1309
      if (optval)
1310
        return (_javanet_create_boolean (env, JNI_TRUE));
1311
      else
1312
        return (_javanet_create_boolean (env, JNI_FALSE));
1313
 
1314
      break;
1315
 
1316
      /* SO_LINGER case.  If disabled, return a Boolean object that represents
1317
         false, else return an Integer that is the value of SO_LINGER */
1318
    case SOCKOPT_SO_LINGER:
1319
      result = cpnet_getLinger (env, fd, &flag, &optval);
1320
 
1321
      if (result != CPNATIVE_OK)
1322
        {
1323
          JCL_ThrowException (env, SOCKET_EXCEPTION,
1324
                              cpnative_getErrorString (result));
1325
          return (0);
1326
        }
1327
 
1328
      if (flag)
1329
        return (_javanet_create_integer (env, optval));
1330
      else
1331
        return (_javanet_create_boolean (env, JNI_FALSE));
1332
 
1333
      break;
1334
 
1335
      /* SO_TIMEOUT case. Return an Integer object with the timeout value */
1336
    case SOCKOPT_SO_TIMEOUT:
1337
      result = cpnet_getSocketTimeout (env, fd, &optval);
1338
      if (result != CPNATIVE_OK)
1339
        {
1340
          JCL_ThrowException (env, SOCKET_EXCEPTION,
1341
                              cpnative_getErrorString (result));
1342
          return (0);
1343
        }
1344
      return (_javanet_create_integer (env, optval));
1345
      break;
1346
 
1347
    case SOCKOPT_SO_SNDBUF:
1348
    case SOCKOPT_SO_RCVBUF:
1349
      if (option_id == SOCKOPT_SO_SNDBUF)
1350
        result = cpnet_getSendBuf (env, fd, &optval);
1351
      else
1352
        result = cpnet_getRecvBuf (env, fd, &optval);
1353
 
1354
      if (result != CPNATIVE_OK)
1355
        {
1356
          JCL_ThrowException (env, SOCKET_EXCEPTION,
1357
                              cpnative_getErrorString (result));
1358
          return (0);
1359
        }
1360
 
1361
      return (_javanet_create_integer (env, optval));
1362
      break;
1363
 
1364
      /* The TTL case.  Return an Integer with the Time to Live value */
1365
    case SOCKOPT_IP_TTL:
1366
      result = cpnet_getTTL (env, fd, &optval);
1367
      if (result != CPNATIVE_OK)
1368
        {
1369
          JCL_ThrowException (env, SOCKET_EXCEPTION,
1370
                              cpnative_getErrorString (result));
1371
          return (0);
1372
        }
1373
 
1374
      return (_javanet_create_integer (env, optval));
1375
      break;
1376
 
1377
      /* Multicast interface case */
1378
    case SOCKOPT_IP_MULTICAST_IF:
1379
      result = cpnet_getMulticastIF (env, fd, &address);
1380
      if (result != CPNATIVE_OK)
1381
        {
1382
          JCL_ThrowException (env, SOCKET_EXCEPTION,
1383
                              cpnative_getErrorString (result));
1384
          return (0);
1385
        }
1386
 
1387
      obj = _javanet_create_inetaddress (env, address);
1388
      cpnet_freeAddress (env, address);
1389
 
1390
      return obj;
1391
      break;
1392
 
1393
    case SOCKOPT_SO_BINDADDR:
1394
      result = cpnet_getLocalAddr (env, fd, &address);
1395
      if (result != CPNATIVE_OK)
1396
        {
1397
          JCL_ThrowException (env, SOCKET_EXCEPTION,
1398
                              cpnative_getErrorString (result));
1399
          return (0);
1400
        }
1401
 
1402
      obj = _javanet_create_inetaddress (env, address);
1403
      cpnet_freeAddress (env, address);
1404
 
1405
      return obj;
1406
      break;
1407
 
1408
    case SOCKOPT_SO_REUSEADDR:
1409
      result = cpnet_getReuseAddress (env, fd, &optval);
1410
      if (result != CPNATIVE_OK)
1411
        {
1412
          JCL_ThrowException (env, SOCKET_EXCEPTION,
1413
                              cpnative_getErrorString (result));
1414
          return (0);
1415
        }
1416
 
1417
      if (optval)
1418
        return _javanet_create_boolean (env, JNI_TRUE);
1419
      else
1420
        return _javanet_create_boolean (env, JNI_FALSE);
1421
 
1422
      break;
1423
 
1424
    case SOCKOPT_SO_KEEPALIVE:
1425
      result = cpnet_getKeepAlive (env, fd, &optval);
1426
      if (result != CPNATIVE_OK)
1427
        {
1428
          JCL_ThrowException (env, SOCKET_EXCEPTION,
1429
                              cpnative_getErrorString (result));
1430
          return (0);
1431
        }
1432
 
1433
      if (optval)
1434
        return _javanet_create_boolean (env, JNI_TRUE);
1435
      else
1436
        return _javanet_create_boolean (env, JNI_FALSE);
1437
 
1438
      break;
1439
 
1440
    default:
1441
      JCL_ThrowException (env, SOCKET_EXCEPTION, "No such option");
1442
      return (0);
1443
    }
1444
 
1445
  return (0);
1446
#else /* not WITHOUT_NETWORK */
1447
#endif /* not WITHOUT_NETWORK */
1448
}
1449
 
1450
void
1451
_javanet_shutdownInput (JNIEnv * env, jobject this)
1452
{
1453
  int result;
1454
  int fd;
1455
 
1456
  /* Get the real file descriptor. */
1457
  fd = _javanet_get_int_field (env, this, "native_fd");
1458
  if (fd == -1)
1459
    {
1460
      JCL_ThrowException (env, SOCKET_EXCEPTION,
1461
                          "Internal error: _javanet_get_option(): no native file descriptor");
1462
      return;
1463
    }
1464
 
1465
  /* Shutdown input stream of socket. */
1466
  result = cpnet_shutdown (env, fd, CPNET_SHUTDOWN_READ);
1467
  if (result != CPNATIVE_OK)
1468
    {
1469
      JCL_ThrowException (env, SOCKET_EXCEPTION,
1470
                          cpnative_getErrorString (result));
1471
      return;
1472
    }
1473
}
1474
 
1475
void
1476
_javanet_shutdownOutput (JNIEnv * env, jobject this)
1477
{
1478
  int fd;
1479
  int result;
1480
 
1481
  /* Get the real file descriptor. */
1482
  fd = _javanet_get_int_field (env, this, "native_fd");
1483
  if (fd == -1)
1484
    {
1485
      JCL_ThrowException (env, SOCKET_EXCEPTION,
1486
                          "Internal error: _javanet_get_option(): no native file descriptor");
1487
      return;
1488
    }
1489
 
1490
  /* Shutdown output stream of socket. */
1491
  result = cpnet_shutdown (env, fd, CPNET_SHUTDOWN_WRITE);
1492
  if (result != CPNATIVE_OK)
1493
    {
1494
      JCL_ThrowException (env, SOCKET_EXCEPTION,
1495
                          cpnative_getErrorString (result));
1496
      return;
1497
    }
1498
}
1499
 
1500
/* end of file */

powered by: WebSVN 2.1.0

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