Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / classpath / native / jni / java-net / javanet.c
blob31afbc869973fd7ca02eb57fbbfdb481065f2b6a
1 /* javanet.c - Common internal functions for the java.net package
2 Copyright (C) 1998, 2002, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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.
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.
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.
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.
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. */
38 /* do not move; needed here because of some macro definitions */
39 #include <config.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <assert.h>
46 #include <jni.h>
47 #include <jcl.h>
49 #include "javanet.h"
51 #include "target_native.h"
52 #ifndef WITHOUT_NETWORK
53 #include "target_native_network.h"
54 #endif /* WITHOUT_NETWORK */
56 #ifndef WITHOUT_NETWORK
57 /* Need to have some value for SO_TIMEOUT */
58 #ifndef SO_TIMEOUT
59 #ifndef SO_RCVTIMEO
60 #warning Neither SO_TIMEOUT or SO_RCVTIMEO are defined!
61 #warning This will cause all get/setOption calls with that value to throw an exception
62 #else
63 #define SO_TIMEOUT SO_RCVTIMEO
64 #endif /* not SO_RCVTIMEO */
65 #endif /* not SO_TIMEOUT */
66 #endif /* WITHOUT_NETWORK */
68 /*************************************************************************/
71 * Sets an integer field in the specified object.
73 static void
74 _javanet_set_int_field (JNIEnv * env, jobject obj,
75 const char *class, const char *field, int val)
77 jclass cls;
78 jfieldID fid;
80 assert (env != NULL);
81 assert ((*env) != NULL);
83 cls = (*env)->FindClass (env, class);
84 if (cls == NULL)
85 return;
87 fid = (*env)->GetFieldID (env, cls, field, "I");
88 if (fid == NULL)
89 return;
91 (*env)->SetIntField (env, obj, fid, val);
93 return;
96 /*************************************************************************/
99 * Returns the value of the specified integer instance variable field or
100 * -1 if an error occurs.
103 _javanet_get_int_field (JNIEnv * env, jobject obj, const char *field)
105 jclass cls = 0;
106 jfieldID fid;
107 int fd;
109 assert (env != NULL);
110 assert ((*env) != NULL);
112 DBG ("_javanet_get_int_field(): Entered _javanet_get_int_field\n");
114 cls = (*env)->GetObjectClass (env, obj);
115 if (cls == NULL)
116 return -1;
118 fid = (*env)->GetFieldID (env, cls, field, "I");
119 if (fid == NULL)
120 return -1;
121 DBG ("_javanet_get_int_field(): Found field id\n");
123 fd = (*env)->GetIntField (env, obj, fid);
125 return fd;
128 /*************************************************************************/
131 * Creates a FileDescriptor object in the parent class. It is not used
132 * by this implementation, but the docs list it as a variable, so we
133 * need to include it.
135 static void
136 _javanet_create_localfd (JNIEnv * env, jobject this)
138 jclass this_cls, fd_cls;
139 jfieldID fid;
140 jmethodID mid;
141 jobject fd_obj;
143 assert (env != NULL);
144 assert ((*env) != NULL);
146 DBG ("_javanet_create_localfd(): Entered _javanet_create_localfd\n");
148 /* Look up the fd field */
149 this_cls = (*env)->FindClass (env, "java/net/SocketImpl");
150 if (this_cls == NULL)
151 return;
153 fid = (*env)->GetFieldID (env, this_cls, "fd", "Ljava/io/FileDescriptor;");
154 if (fid == NULL)
155 return;
157 DBG ("_javanet_create_localfd(): Found fd variable\n");
159 /* Create a FileDescriptor */
160 fd_cls = (*env)->FindClass (env, "java/io/FileDescriptor");
161 if (fd_cls == NULL)
162 return;
164 DBG ("_javanet_create_localfd(): Found FileDescriptor class\n");
166 mid = (*env)->GetMethodID (env, fd_cls, "<init>", "()V");
167 if (mid == NULL)
168 return;
170 DBG ("_javanet_create_localfd(): Found FileDescriptor constructor\n");
172 fd_obj = (*env)->NewObject (env, fd_cls, mid);
173 if (fd_obj == NULL)
174 return;
176 DBG ("_javanet_create_localfd(): Created FileDescriptor\n");
178 /* Now set the pointer to the new FileDescriptor */
179 (*env)->SetObjectField (env, this, fid, fd_obj);
180 DBG ("_javanet_create_localfd(): Set fd field\n");
182 return;
185 /*************************************************************************/
188 * Returns a Boolean object with the specfied value
190 static jobject
191 _javanet_create_boolean (JNIEnv * env, jboolean val)
193 jclass cls;
194 jmethodID mid;
195 jobject obj;
197 assert (env != NULL);
198 assert ((*env) != NULL);
200 cls = (*env)->FindClass (env, "java/lang/Boolean");
201 if (cls == NULL)
202 return NULL;
204 mid = (*env)->GetMethodID (env, cls, "<init>", "(Z)V");
205 if (mid == NULL)
206 return NULL;
208 obj = (*env)->NewObject (env, cls, mid, val);
209 if (obj == NULL)
210 return NULL;
212 return obj;
215 /*************************************************************************/
218 * Returns an Integer object with the specfied value
220 static jobject
221 _javanet_create_integer (JNIEnv * env, jint val)
223 jclass cls;
224 jmethodID mid;
225 jobject obj;
227 assert (env != NULL);
228 assert ((*env) != NULL);
230 cls = (*env)->FindClass (env, "java/lang/Integer");
231 if (cls == NULL)
232 return NULL;
234 mid = (*env)->GetMethodID (env, cls, "<init>", "(I)V");
235 if (mid == NULL)
236 return NULL;
238 obj = (*env)->NewObject (env, cls, mid, val);
239 if (obj == NULL)
240 return NULL;
242 return obj;
245 /*************************************************************************/
248 * Builds an InetAddress object from a 32 bit address in host byte order
250 static jobject
251 _javanet_create_inetaddress (JNIEnv * env, int netaddr)
253 #ifndef WITHOUT_NETWORK
254 unsigned char octets[4];
255 char buf[16];
256 jclass ia_cls;
257 jmethodID mid;
258 jstring ip_str;
259 jobject ia;
261 assert (env != NULL);
262 assert ((*env) != NULL);
264 /* Build a string IP address */
265 TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES (netaddr,
266 octets[0],
267 octets[1],
268 octets[2], octets[3]);
269 sprintf (buf, "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]);
270 DBG ("_javanet_create_inetaddress(): Created ip addr string\n");
272 /* Get an InetAddress object for this IP */
273 ia_cls = (*env)->FindClass (env, "java/net/InetAddress");
274 if (ia_cls == NULL)
276 return NULL;
279 DBG ("_javanet_create_inetaddress(): Found InetAddress class\n");
281 mid = (*env)->GetStaticMethodID (env, ia_cls, "getByName",
282 "(Ljava/lang/String;)Ljava/net/InetAddress;");
283 if (mid == NULL)
285 return NULL;
288 DBG ("_javanet_create_inetaddress(): Found getByName method\n");
290 ip_str = (*env)->NewStringUTF (env, buf);
291 if (ip_str == NULL)
293 return NULL;
296 ia = (*env)->CallStaticObjectMethod (env, ia_cls, mid, ip_str);
297 if (ia == NULL)
299 return NULL;
302 DBG ("_javanet_create_inetaddress(): Called getByName method\n");
304 return ia;
305 #else /* not WITHOUT_NETWORK */
306 return NULL;
307 #endif /* not WITHOUT_NETWORK */
310 /*************************************************************************/
312 static void
313 _javanet_set_remhost_addr (JNIEnv * env, jobject this, jobject ia)
315 jclass this_cls;
316 jfieldID fid;
318 assert (env != NULL);
319 assert ((*env) != NULL);
321 /* Set the variable in the object */
322 this_cls = (*env)->FindClass (env, "java/net/SocketImpl");
323 if (this_cls == NULL)
324 return;
326 fid =
327 (*env)->GetFieldID (env, this_cls, "address", "Ljava/net/InetAddress;");
328 if (fid == NULL)
329 return;
331 DBG ("_javanet_set_remhost_addr(): Found address field\n");
333 (*env)->SetObjectField (env, this, fid, ia);
334 DBG ("_javanet_set_remhost_addr(): Set field\n");
338 * Set's the value of the "addr" field in PlainSocketImpl with a new
339 * InetAddress for the specified addr
341 static void
342 _javanet_set_remhost (JNIEnv * env, jobject this, int netaddr)
344 jobject ia;
346 assert (env != NULL);
347 assert ((*env) != NULL);
349 DBG ("_javanet_set_remhost(): Entered _javanet_set_remhost\n");
351 /* Get an InetAddress object */
352 ia = _javanet_create_inetaddress (env, netaddr);
353 if (ia == NULL)
354 return;
356 _javanet_set_remhost_addr (env, this, ia);
360 /*************************************************************************/
363 * Returns a 32 bit Internet address for the passed in InetAddress object
366 _javanet_get_netaddr (JNIEnv * env, jobject addr)
368 #ifndef WITHOUT_NETWORK
369 jclass cls = 0;
370 jmethodID mid;
371 jarray arr = 0;
372 jbyte *octets;
373 int netaddr, len;
375 assert (env != NULL);
376 assert ((*env) != NULL);
378 DBG ("_javanet_get_netaddr(): Entered _javanet_get_netaddr\n");
380 if (addr == NULL)
382 JCL_ThrowException (env, "java/lang/NullPointerException",
383 "Null address");
384 return 0;
387 /* Call the getAddress method on the object to retrieve the IP address */
388 cls = (*env)->GetObjectClass (env, addr);
389 if (cls == NULL)
390 return 0;
392 mid = (*env)->GetMethodID (env, cls, "getAddress", "()[B");
393 if (mid == NULL)
394 return 0;
396 DBG ("_javanet_get_netaddr(): Got getAddress method\n");
398 arr = (*env)->CallObjectMethod (env, addr, mid);
399 if (arr == NULL)
400 return 0;
402 DBG ("_javanet_get_netaddr(): Got the address\n");
404 /* Turn the IP address into a 32 bit Internet address in network byte order */
405 len = (*env)->GetArrayLength (env, arr);
406 if (len != 4)
408 JCL_ThrowException (env, IO_EXCEPTION, "Internal Error");
409 return 0;
411 DBG ("_javanet_get_netaddr(): Length ok\n");
413 octets = (*env)->GetByteArrayElements (env, arr, 0);
414 if (octets == NULL)
415 return 0;
417 DBG ("_javanet_get_netaddr(): Grabbed bytes\n");
419 TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT (octets[0],
420 octets[1],
421 octets[2],
422 octets[3], netaddr);
424 (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
425 DBG ("_javanet_get_netaddr(): Done getting addr\n");
427 return netaddr;
428 #else /* not WITHOUT_NETWORK */
429 #endif /* not WITHOUT_NETWORK */
432 /*************************************************************************/
435 * Creates a new stream or datagram socket
437 void
438 _javanet_create (JNIEnv * env, jobject this, jboolean stream)
440 #ifndef WITHOUT_NETWORK
441 int fd;
442 int result;
444 assert (env != NULL);
445 assert ((*env) != NULL);
447 if (stream)
449 /* create a stream socket */
450 TARGET_NATIVE_NETWORK_SOCKET_OPEN_STREAM (fd, result);
451 if (result != TARGET_NATIVE_OK)
453 JCL_ThrowException (env, IO_EXCEPTION,
454 TARGET_NATIVE_LAST_ERROR_STRING ());
455 return;
458 else
460 /* create a datagram socket, set broadcast option */
461 TARGET_NATIVE_NETWORK_SOCKET_OPEN_DATAGRAM (fd, result);
462 if (result != TARGET_NATIVE_OK)
464 JCL_ThrowException (env, IO_EXCEPTION,
465 TARGET_NATIVE_LAST_ERROR_STRING ());
466 return;
468 TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_BROADCAST (fd, 1, result);
469 if (result != TARGET_NATIVE_OK)
471 JCL_ThrowException (env, IO_EXCEPTION,
472 TARGET_NATIVE_LAST_ERROR_STRING ());
473 return;
477 if (stream)
478 _javanet_set_int_field (env, this, "gnu/java/net/PlainSocketImpl",
479 "native_fd", fd);
480 else
481 _javanet_set_int_field (env, this, "gnu/java/net/PlainDatagramSocketImpl",
482 "native_fd", fd);
484 if ((*env)->ExceptionOccurred (env))
486 /* Try to make sure we close the socket since close() won't work. */
489 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
490 if (result != TARGET_NATIVE_OK
491 && (TARGET_NATIVE_LAST_ERROR ()
492 != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
493 return;
495 while (result != TARGET_NATIVE_OK);
496 return;
499 #else /* not WITHOUT_NETWORK */
500 #endif /* not WITHOUT_NETWORK */
503 /*************************************************************************/
506 * Close the socket. Any underlying streams will be closed by this
507 * action as well.
509 void
510 _javanet_close (JNIEnv * env, jobject this, int stream)
512 #ifndef WITHOUT_NETWORK
513 int fd;
514 int result;
515 int error = 0;
517 assert (env != NULL);
518 assert ((*env) != NULL);
520 fd = _javanet_get_int_field (env, this, "native_fd");
521 if (fd == -1)
522 return;
524 if (stream)
525 _javanet_set_int_field (env, this, "gnu/java/net/PlainSocketImpl",
526 "native_fd", -1);
527 else
528 _javanet_set_int_field (env, this, "gnu/java/net/PlainDatagramSocketImpl",
529 "native_fd", -1);
532 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
533 if (result != TARGET_NATIVE_OK)
535 /* Only throw an error when a "real" error occurs. */
536 error = TARGET_NATIVE_LAST_ERROR ();
537 if (error != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL
538 && error != ENOTCONN && error != ECONNRESET && error != EBADF)
539 JCL_ThrowException (env, IO_EXCEPTION,
540 TARGET_NATIVE_LAST_ERROR_STRING ());
543 while (error == TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL);
545 #else /* not WITHOUT_NETWORK */
546 #endif /* not WITHOUT_NETWORK */
549 /*************************************************************************/
552 * Connects to the specified destination.
554 void
555 _javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port)
557 #ifndef WITHOUT_NETWORK
558 int netaddr, fd;
559 int result;
560 int local_address, local_port;
561 int remote_address, remote_port;
563 assert (env != NULL);
564 assert ((*env) != NULL);
566 DBG ("_javanet_connect(): Entered _javanet_connect\n");
568 /* Pre-process input variables */
569 netaddr = _javanet_get_netaddr (env, addr);
570 if ((*env)->ExceptionOccurred (env))
571 return;
573 if (port == -1)
574 port = 0;
575 DBG ("_javanet_connect(): Got network address\n");
577 /* Grab the real socket file descriptor */
578 fd = _javanet_get_int_field (env, this, "native_fd");
579 if (fd == -1)
581 JCL_ThrowException (env, IO_EXCEPTION,
582 "Internal error: _javanet_connect(): no native file descriptor");
583 return;
585 DBG ("_javanet_connect(): Got native fd\n");
587 /* Connect up */
590 TARGET_NATIVE_NETWORK_SOCKET_CONNECT (fd, netaddr, port, result);
591 if (result != TARGET_NATIVE_OK
592 && (TARGET_NATIVE_LAST_ERROR ()
593 != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
595 JCL_ThrowException (env, IO_EXCEPTION,
596 TARGET_NATIVE_LAST_ERROR_STRING ());
597 return;
600 while (result != TARGET_NATIVE_OK);
602 DBG ("_javanet_connect(): Connected successfully\n");
604 /* Populate instance variables */
605 TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (fd, local_address, local_port,
606 result);
607 if (result != TARGET_NATIVE_OK)
609 JCL_ThrowException (env, IO_EXCEPTION,
610 TARGET_NATIVE_LAST_ERROR_STRING ());
611 /* We don't care whether this succeeds. close() will cleanup later. */
612 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
613 return;
616 _javanet_create_localfd (env, this);
617 if ((*env)->ExceptionOccurred (env))
619 /* We don't care whether this succeeds. close() will cleanup later. */
620 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
621 return;
623 DBG ("_javanet_connect(): Created fd\n");
625 _javanet_set_int_field (env, this, "java/net/SocketImpl", "localport",
626 local_port);
627 if ((*env)->ExceptionOccurred (env))
629 /* We don't care whether this succeeds. close() will cleanup later. */
630 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
631 return;
633 DBG ("_javanet_connect(): Set the local port\n");
635 TARGET_NATIVE_NETWORK_SOCKET_GET_REMOTE_INFO (fd, remote_address,
636 remote_port, result);
637 if (result != TARGET_NATIVE_OK)
639 JCL_ThrowException (env, IO_EXCEPTION,
640 TARGET_NATIVE_LAST_ERROR_STRING ());
641 /* We don't care whether this succeeds. close() will cleanup later. */
642 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
643 return;
646 if (remote_address == netaddr)
648 _javanet_set_remhost_addr (env, this, addr);
650 else
652 _javanet_set_remhost (env, this, remote_address);
654 if ((*env)->ExceptionOccurred (env))
656 /* We don't care whether this succeeds. close() will cleanup later. */
657 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
658 return;
660 DBG ("_javanet_connect(): Set the remote host\n");
662 _javanet_set_int_field (env, this, "java/net/SocketImpl", "port",
663 remote_port);
664 if ((*env)->ExceptionOccurred (env))
666 /* We don't care whether this succeeds. close() will cleanup later. */
667 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
668 return;
670 DBG ("_javanet_connect(): Set the remote port\n");
671 #else /* not WITHOUT_NETWORK */
672 #endif /* not WITHOUT_NETWORK */
675 /*************************************************************************/
678 * This method binds the specified address to the specified local port.
679 * Note that we have to set the local address and local
680 * port public instance variables.
682 void
683 _javanet_bind (JNIEnv * env, jobject this, jobject addr, jint port,
684 int stream)
686 #ifndef WITHOUT_NETWORK
687 jclass cls;
688 jmethodID mid;
689 jbyteArray arr = 0;
690 jbyte *octets;
691 jint fd;
692 int tmpaddr;
693 int result;
694 int local_address, local_port;
696 assert (env != NULL);
697 assert ((*env) != NULL);
699 DBG ("_javanet_bind(): Entering native bind()\n");
701 /* Get the address to connect to */
702 cls = (*env)->GetObjectClass (env, addr);
703 if (cls == NULL)
704 return;
706 mid = (*env)->GetMethodID (env, cls, "getAddress", "()[B");
707 if (mid == NULL)
708 return;
710 DBG ("_javanet_bind(): Past getAddress method id\n");
712 arr = (*env)->CallObjectMethod (env, addr, mid);
713 if ((arr == NULL) || (*env)->ExceptionOccurred (env))
715 JCL_ThrowException (env, IO_EXCEPTION,
716 "Internal error: _javanet_bind()");
717 return;
720 DBG ("_javanet_bind(): Past call object method\n");
722 octets = (*env)->GetByteArrayElements (env, arr, 0);
723 if (octets == NULL)
724 return;
726 DBG ("_javanet_bind(): Past grab array\n");
728 /* Get the native socket file descriptor */
729 fd = _javanet_get_int_field (env, this, "native_fd");
730 if (fd == -1)
732 (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
733 JCL_ThrowException (env, IO_EXCEPTION,
734 "Internal error: _javanet_bind(): no native file descriptor");
735 return;
737 DBG ("_javanet_bind(): Past native_fd lookup\n");
739 /* XXX NYI ??? */
740 _javanet_set_option (env, this, SOCKOPT_SO_REUSEADDR,
741 _javanet_create_boolean (env, JNI_TRUE));
744 /* Bind the socket */
745 TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT (octets[0],
746 octets[1],
747 octets[2],
748 octets[3], tmpaddr);
749 TARGET_NATIVE_NETWORK_SOCKET_BIND (fd, tmpaddr, port, result);
751 if (result != TARGET_NATIVE_OK)
753 char *errorstr = TARGET_NATIVE_LAST_ERROR_STRING ();
754 (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
756 JCL_ThrowException (env, BIND_EXCEPTION,
757 errorstr);
758 return;
760 DBG ("_javanet_bind(): Past bind\n");
762 (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
764 /* Update instance variables, specifically the local port number */
765 TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (fd, local_address, local_port,
766 result);
767 if (result != TARGET_NATIVE_OK)
769 JCL_ThrowException (env, IO_EXCEPTION,
770 TARGET_NATIVE_LAST_ERROR_STRING ());
771 return;
774 if (stream)
775 _javanet_set_int_field (env, this, "java/net/SocketImpl",
776 "localport", local_port);
777 else
778 _javanet_set_int_field (env, this, "java/net/DatagramSocketImpl",
779 "localPort", local_port);
780 DBG ("_javanet_bind(): Past update port number\n");
782 return;
783 #else /* not WITHOUT_NETWORK */
784 #endif /* not WITHOUT_NETWORK */
787 /*************************************************************************/
790 * Starts listening on a socket with the specified number of pending
791 * connections allowed.
793 void
794 _javanet_listen (JNIEnv * env, jobject this, jint queuelen)
796 #ifndef WITHOUT_NETWORK
797 int fd;
798 int result;
800 assert (env != NULL);
801 assert ((*env) != NULL);
803 /* Get the real file descriptor */
804 fd = _javanet_get_int_field (env, this, "native_fd");
805 if (fd == -1)
807 JCL_ThrowException (env, IO_EXCEPTION,
808 "Internal error: _javanet_listen(): no native file descriptor");
809 return;
812 /* Start listening */
813 TARGET_NATIVE_NETWORK_SOCKET_LISTEN (fd, queuelen, result);
814 if (result != TARGET_NATIVE_OK)
816 JCL_ThrowException (env, IO_EXCEPTION,
817 TARGET_NATIVE_LAST_ERROR_STRING ());
818 return;
820 #else /* not WITHOUT_NETWORK */
821 #endif /* not WITHOUT_NETWORK */
824 /*************************************************************************/
827 * Accepts a new connection and assigns it to the passed in SocketImpl
828 * object. Note that we assume this is a PlainSocketImpl just like us
830 void
831 _javanet_accept (JNIEnv * env, jobject this, jobject impl)
833 #ifndef WITHOUT_NETWORK
834 int fd, newfd;
835 int result;
836 int local_address, local_port;
837 int remote_address, remote_port;
839 assert (env != NULL);
840 assert ((*env) != NULL);
842 /* Get the real file descriptor */
843 fd = _javanet_get_int_field (env, this, "native_fd");
844 if (fd == -1)
846 JCL_ThrowException (env, IO_EXCEPTION,
847 "Internal error: _javanet_accept(): no native file descriptor");
848 return;
851 /* Accept the connection */
854 TARGET_NATIVE_NETWORK_SOCKET_ACCEPT (fd, newfd, result);
855 if (result != TARGET_NATIVE_OK
856 && (TARGET_NATIVE_LAST_ERROR ()
857 != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
859 if (TARGET_NATIVE_LAST_ERROR () == EAGAIN)
860 JCL_ThrowException (env, "java/net/SocketTimeoutException",
861 "Timeout");
862 else
863 JCL_ThrowException (env, IO_EXCEPTION,
864 TARGET_NATIVE_LAST_ERROR_STRING ());
865 return;
868 while (result != TARGET_NATIVE_OK);
870 /* Populate instance variables */
871 _javanet_set_int_field (env, impl, "gnu/java/net/PlainSocketImpl",
872 "native_fd", newfd);
874 if ((*env)->ExceptionOccurred (env))
876 /* Try to make sure we close the socket since close() won't work. */
879 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
880 if (result != TARGET_NATIVE_OK
881 && (TARGET_NATIVE_LAST_ERROR ()
882 != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
883 return;
885 while (result != TARGET_NATIVE_OK);
886 return;
889 TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (newfd, local_address,
890 local_port, result);
891 if (result != TARGET_NATIVE_OK)
893 /* We don't care whether this succeeds. close() will cleanup later. */
894 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
895 JCL_ThrowException (env, IO_EXCEPTION,
896 TARGET_NATIVE_LAST_ERROR_STRING ());
897 return;
900 _javanet_create_localfd (env, impl);
901 if ((*env)->ExceptionOccurred (env))
903 /* We don't care whether this succeeds. close() will cleanup later. */
904 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
905 return;
908 _javanet_set_int_field (env, impl, "java/net/SocketImpl", "localport",
909 local_port);
910 if ((*env)->ExceptionOccurred (env))
912 /* We don't care whether this succeeds. close() will cleanup later. */
913 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
914 return;
917 TARGET_NATIVE_NETWORK_SOCKET_GET_REMOTE_INFO (newfd, remote_address,
918 remote_port, result);
919 if (result != TARGET_NATIVE_OK)
921 JCL_ThrowException (env, IO_EXCEPTION,
922 TARGET_NATIVE_LAST_ERROR_STRING ());
923 /* We don't care whether this succeeds. close() will cleanup later. */
924 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
925 return;
928 _javanet_set_remhost (env, impl, remote_address);
929 if ((*env)->ExceptionOccurred (env))
931 /* We don't care whether this succeeds. close() will cleanup later. */
932 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
933 return;
936 _javanet_set_int_field (env, impl, "java/net/SocketImpl", "port",
937 remote_port);
938 if ((*env)->ExceptionOccurred (env))
940 /* We don't care whether this succeeds. close() will cleanup later. */
941 TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
942 return;
944 #else /* not WITHOUT_NETWORK */
945 #endif /* not WITHOUT_NETWORK */
948 /*************************************************************************/
951 * Receives a buffer from a remote host. The args are:
953 * buf - The byte array into which the data received will be written
954 * offset - Offset into the byte array to start writing
955 * len - The number of bytes to read.
956 * addr - Pointer to 32 bit net address of host to receive from. If null,
957 * this parm is ignored. If pointing to an address of 0, the
958 * actual address read is stored here
959 * port - Pointer to the port to receive from. If null, this parm is ignored.
960 * If it is 0, the actual remote port received from is stored here
962 * The actual number of bytes read is returned.
965 _javanet_recvfrom (JNIEnv * env, jobject this, jarray buf, int offset,
966 int len, int *addr, int *port)
968 #ifndef WITHOUT_NETWORK
969 int fd;
970 jbyte *p;
971 int from_address, from_port;
972 int received_bytes;
974 assert (env != NULL);
975 assert ((*env) != NULL);
977 DBG ("_javanet_recvfrom(): Entered _javanet_recvfrom\n");
979 /* Get the real file descriptor */
980 fd = _javanet_get_int_field (env, this, "native_fd");
981 if (fd == -1)
983 JCL_ThrowException (env, IO_EXCEPTION,
984 "Internal error: _javanet_recvfrom(): no native file descriptor");
985 return 0;
987 DBG ("_javanet_recvfrom(): Got native_fd\n");
989 /* Get a pointer to the buffer */
990 p = (*env)->GetByteArrayElements (env, buf, 0);
991 if (p == NULL)
992 return 0;
994 DBG ("_javanet_recvfrom(): Got buffer\n");
996 /* Read the data */
997 from_address = 0;
998 from_port = 0;
1001 if (addr != NULL)
1003 TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_WITH_ADDRESS_PORT (fd,
1004 p + offset,
1005 len,
1006 from_address,
1007 from_port,
1008 received_bytes);
1010 else
1012 TARGET_NATIVE_NETWORK_SOCKET_RECEIVE (fd, p + offset, len,
1013 received_bytes);
1016 while ((received_bytes == -1) &&
1017 (TARGET_NATIVE_LAST_ERROR () ==
1018 TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL));
1020 if (received_bytes == -1)
1022 if (TARGET_NATIVE_LAST_ERROR () == EAGAIN)
1023 JCL_ThrowException (env, "java/net/SocketTimeoutException", "Timeout");
1024 else
1025 JCL_ThrowException (env, IO_EXCEPTION,
1026 TARGET_NATIVE_LAST_ERROR_STRING ());
1028 /* Cleanup and return. */
1029 (*env)->ReleaseByteArrayElements (env, buf, p, 0);
1030 return 0;
1033 (*env)->ReleaseByteArrayElements (env, buf, p, 0);
1035 /* Handle return addr case */
1036 if (addr != NULL)
1038 (*addr) = from_address;
1039 if (port != NULL)
1040 (*port) = from_port;
1043 return (received_bytes);
1044 #else /* not WITHOUT_NETWORK */
1045 #endif /* not WITHOUT_NETWORK */
1048 /*************************************************************************/
1051 * Sends a buffer to a remote host. The args are:
1053 * buf - A byte array
1054 * offset - Index into the byte array to start sendign
1055 * len - The number of bytes to write
1056 * addr - The 32bit address to send to (may be 0)
1057 * port - The port number to send to (may be 0)
1059 void
1060 _javanet_sendto (JNIEnv * env, jobject this, jarray buf, int offset, int len,
1061 int addr, int port)
1063 #ifndef WITHOUT_NETWORK
1064 int fd;
1065 jbyte *p;
1066 int bytes_sent;
1068 assert (env != NULL);
1069 assert ((*env) != NULL);
1071 /* Get the real file descriptor */
1072 fd = _javanet_get_int_field (env, this, "native_fd");
1073 if (fd == -1)
1075 JCL_ThrowException (env, IO_EXCEPTION,
1076 "Internal error: _javanet_sendto(): no native file descriptor");
1077 return;
1080 /* Get a pointer to the buffer */
1081 p = (*env)->GetByteArrayElements (env, buf, 0);
1082 if (p == NULL)
1083 return;
1085 /* We must send all the data, so repeat till done. */
1086 while (len > 0)
1088 /* Send the data */
1089 if (addr == 0)
1091 DBG ("_javanet_sendto(): Sending....\n");
1092 TARGET_NATIVE_NETWORK_SOCKET_SEND (fd, p + offset, len, bytes_sent);
1094 else
1096 DBG ("_javanet_sendto(): Sending....\n");
1097 TARGET_NATIVE_NETWORK_SOCKET_SEND_WITH_ADDRESS_PORT (fd, p + offset,
1098 len, addr, port,
1099 bytes_sent);
1102 if (bytes_sent < 0)
1104 if (TARGET_NATIVE_LAST_ERROR ()
1105 != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)
1107 JCL_ThrowException (env, IO_EXCEPTION,
1108 TARGET_NATIVE_LAST_ERROR_STRING ());
1109 break;
1112 else
1114 len -= bytes_sent;
1115 addr += bytes_sent;
1119 (*env)->ReleaseByteArrayElements (env, buf, p, 0);
1121 #else /* not WITHOUT_NETWORK */
1122 #endif /* not WITHOUT_NETWORK */
1125 /*************************************************************************/
1128 * Sets the specified option for a socket
1130 void
1131 _javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
1133 #ifndef WITHOUT_NETWORK
1134 int fd;
1135 int optval;
1136 jclass cls;
1137 jmethodID mid;
1138 int address;
1139 int result;
1141 assert (env != NULL);
1142 assert ((*env) != NULL);
1144 /* Get the real file descriptor */
1145 fd = _javanet_get_int_field (env, this, "native_fd");
1146 if (fd == -1)
1148 JCL_ThrowException (env, IO_EXCEPTION,
1149 "Internal error: _javanet_set_option(): no native file descriptor");
1150 return;
1153 /* We need a class object for all cases below */
1154 cls = (*env)->GetObjectClass (env, val);
1155 if (cls == NULL)
1156 return;
1158 /* Process the option request */
1159 result = TARGET_NATIVE_ERROR;
1160 switch (option_id)
1162 /* TCP_NODELAY case. val is a Boolean that tells us what to do */
1163 case SOCKOPT_TCP_NODELAY:
1164 mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
1165 if (mid == NULL)
1167 JCL_ThrowException (env, IO_EXCEPTION,
1168 "Internal error: _javanet_set_option()");
1169 return;
1172 /* Should be a 0 or a 1 */
1173 optval = (*env)->CallBooleanMethod (env, val, mid);
1174 if ((*env)->ExceptionOccurred (env))
1175 return;
1177 TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_TCP_NODELAY (fd, optval,
1178 result);
1179 break;
1181 /* SO_LINGER case. If val is a boolean, then it will always be set
1182 to false indicating disable linger, otherwise it will be an
1183 integer that contains the linger value */
1184 case SOCKOPT_SO_LINGER:
1185 mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
1186 if (mid)
1188 /* We are disabling linger */
1189 TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_LINGER (fd, 1, 0,
1190 result);
1192 else
1194 /* Clear exception if thrown for failure to do method lookup
1195 above */
1196 if ((*env)->ExceptionOccurred (env))
1197 (*env)->ExceptionClear (env);
1199 mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
1200 if (mid == NULL)
1202 JCL_ThrowException (env, IO_EXCEPTION,
1203 "Internal error: _javanet_set_option()");
1204 return;
1207 optval = (*env)->CallIntMethod (env, val, mid);
1208 if ((*env)->ExceptionOccurred (env))
1209 return;
1211 TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_LINGER (fd, 0, optval,
1212 result);
1214 break;
1216 /* SO_TIMEOUT case. Val will be an integer with the new value */
1217 /* Not writable on Linux */
1218 case SOCKOPT_SO_TIMEOUT:
1219 #ifdef SO_TIMEOUT
1220 mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
1221 if (mid == NULL)
1223 JCL_ThrowException (env, IO_EXCEPTION,
1224 "Internal error: _javanet_set_option()");
1225 return;
1228 optval = (*env)->CallIntMethod (env, val, mid);
1229 if ((*env)->ExceptionOccurred (env))
1230 return;
1232 TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_TIMEOUT (fd, optval, result);
1233 #else
1234 result = TARGET_NATIVE_OK;
1235 #endif
1236 break;
1238 case SOCKOPT_SO_SNDBUF:
1239 case SOCKOPT_SO_RCVBUF:
1240 mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
1241 if (mid == NULL)
1243 JCL_ThrowException (env, IO_EXCEPTION,
1244 "Internal error: _javanet_set_option()");
1245 return;
1249 optval = (*env)->CallIntMethod (env, val, mid);
1250 if ((*env)->ExceptionOccurred (env))
1251 return;
1253 if (option_id == SOCKOPT_SO_SNDBUF)
1254 TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_SNDBUF (fd, optval,
1255 result);
1256 else
1257 TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_RCDBUF (fd, optval,
1258 result);
1259 break;
1261 /* TTL case. Val with be an Integer with the new time to live value */
1262 case SOCKOPT_IP_TTL:
1263 mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
1264 if (!mid)
1266 JCL_ThrowException (env, IO_EXCEPTION,
1267 "Internal error: _javanet_set_option()");
1268 return;
1271 optval = (*env)->CallIntMethod (env, val, mid);
1272 if ((*env)->ExceptionOccurred (env))
1273 return;
1275 TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_TTL (fd, optval, result);
1276 break;
1278 /* Multicast Interface case - val is InetAddress object */
1279 case SOCKOPT_IP_MULTICAST_IF:
1280 address = _javanet_get_netaddr (env, val);
1282 if ((*env)->ExceptionOccurred (env))
1283 return;
1285 TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_MULTICAST_IF (fd, address,
1286 result);
1287 break;
1289 case SOCKOPT_SO_REUSEADDR:
1290 mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
1291 if (mid == NULL)
1293 JCL_ThrowException (env, IO_EXCEPTION,
1294 "Internal error: _javanet_set_option()");
1295 return;
1298 /* Should be a 0 or a 1 */
1299 optval = (*env)->CallBooleanMethod (env, val, mid);
1300 if ((*env)->ExceptionOccurred (env))
1301 return;
1303 TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_REUSE_ADDRESS (fd, optval,
1304 result);
1305 break;
1307 case SOCKOPT_SO_KEEPALIVE:
1308 mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
1309 if (mid == NULL)
1311 JCL_ThrowException (env, IO_EXCEPTION,
1312 "Internal error: _javanet_set_option()");
1313 return;
1316 /* Should be a 0 or a 1 */
1317 optval = (*env)->CallBooleanMethod (env, val, mid);
1318 if ((*env)->ExceptionOccurred (env))
1319 return;
1321 TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_KEEP_ALIVE (fd, optval, result);
1322 break;
1324 case SOCKOPT_SO_BINDADDR:
1325 JCL_ThrowException (env, SOCKET_EXCEPTION, "This option cannot be set");
1326 break;
1328 default:
1329 JCL_ThrowException (env, SOCKET_EXCEPTION, "Unrecognized option");
1330 return;
1333 /* Check to see if above operations succeeded */
1334 if (result != TARGET_NATIVE_OK)
1336 JCL_ThrowException (env, SOCKET_EXCEPTION,
1337 TARGET_NATIVE_LAST_ERROR_STRING ());
1338 return;
1340 #else /* not WITHOUT_NETWORK */
1341 #endif /* not WITHOUT_NETWORK */
1344 /*************************************************************************/
1347 * Retrieves the specified option values for a socket
1349 jobject
1350 _javanet_get_option (JNIEnv * env, jobject this, jint option_id)
1352 #ifndef WITHOUT_NETWORK
1353 int fd;
1354 int flag, optval;
1355 int address;
1356 int result;
1358 assert (env != NULL);
1359 assert ((*env) != NULL);
1361 /* Get the real file descriptor */
1362 fd = _javanet_get_int_field (env, this, "native_fd");
1363 if (fd == -1)
1365 JCL_ThrowException (env, SOCKET_EXCEPTION,
1366 "Internal error: _javanet_get_option(): no native file descriptor");
1367 return (0);
1370 /* Process the option requested */
1371 switch (option_id)
1373 /* TCP_NODELAY case. Return a Boolean indicating on or off */
1374 case SOCKOPT_TCP_NODELAY:
1375 TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_TCP_NODELAY (fd, optval,
1376 result);
1377 if (result != TARGET_NATIVE_OK)
1379 JCL_ThrowException (env, SOCKET_EXCEPTION,
1380 TARGET_NATIVE_LAST_ERROR_STRING ());
1381 return (0);
1384 if (optval)
1385 return (_javanet_create_boolean (env, JNI_TRUE));
1386 else
1387 return (_javanet_create_boolean (env, JNI_FALSE));
1389 break;
1391 /* SO_LINGER case. If disabled, return a Boolean object that represents
1392 false, else return an Integer that is the value of SO_LINGER */
1393 case SOCKOPT_SO_LINGER:
1394 TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_LINGER (fd, flag, optval,
1395 result);
1396 if (result != TARGET_NATIVE_OK)
1398 JCL_ThrowException (env, SOCKET_EXCEPTION,
1399 TARGET_NATIVE_LAST_ERROR_STRING ());
1400 return (0);
1403 if (optval)
1404 return (_javanet_create_integer (env, JNI_TRUE));
1405 else
1406 return (_javanet_create_boolean (env, JNI_FALSE));
1408 break;
1410 /* SO_TIMEOUT case. Return an Integer object with the timeout value */
1411 case SOCKOPT_SO_TIMEOUT:
1412 #ifdef SO_TIMEOUT
1413 TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_TIMEOUT (fd, optval, result);
1414 if (result != TARGET_NATIVE_OK)
1416 JCL_ThrowException (env, SOCKET_EXCEPTION,
1417 TARGET_NATIVE_LAST_ERROR_STRING ());
1418 return (0);
1420 return (_javanet_create_integer (env, optval));
1421 #else
1422 JCL_ThrowException (env, SOCKET_EXCEPTION,
1423 "SO_TIMEOUT not supported on this platform");
1424 return (0);
1425 #endif /* not SO_TIMEOUT */
1426 break;
1428 case SOCKOPT_SO_SNDBUF:
1429 case SOCKOPT_SO_RCVBUF:
1430 if (option_id == SOCKOPT_SO_SNDBUF)
1431 TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_SNDBUF (fd, optval,
1432 result);
1433 else
1434 TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_RCDBUF (fd, optval,
1435 result);
1436 if (result != TARGET_NATIVE_OK)
1438 JCL_ThrowException (env, SOCKET_EXCEPTION,
1439 TARGET_NATIVE_LAST_ERROR_STRING ());
1440 return (0);
1443 return (_javanet_create_integer (env, optval));
1444 break;
1446 /* The TTL case. Return an Integer with the Time to Live value */
1447 case SOCKOPT_IP_TTL:
1448 TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_TTL (fd, optval, result);
1449 if (result != TARGET_NATIVE_OK)
1451 JCL_ThrowException (env, SOCKET_EXCEPTION,
1452 TARGET_NATIVE_LAST_ERROR_STRING ());
1453 return (0);
1456 return (_javanet_create_integer (env, optval));
1457 break;
1459 /* Multicast interface case */
1460 case SOCKOPT_IP_MULTICAST_IF:
1461 TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_MULTICAST_IF (fd, address,
1462 result);
1463 if (result != TARGET_NATIVE_OK)
1465 JCL_ThrowException (env, SOCKET_EXCEPTION,
1466 TARGET_NATIVE_LAST_ERROR_STRING ());
1467 return (0);
1470 return (_javanet_create_inetaddress (env, address));
1471 break;
1473 case SOCKOPT_SO_BINDADDR:
1474 TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_BIND_ADDRESS (fd, address,
1475 result);
1476 if (result != TARGET_NATIVE_OK)
1478 JCL_ThrowException (env, SOCKET_EXCEPTION,
1479 TARGET_NATIVE_LAST_ERROR_STRING ());
1480 return (0);
1483 return (_javanet_create_inetaddress (env, address));
1484 break;
1486 case SOCKOPT_SO_REUSEADDR:
1487 TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_REUSE_ADDRESS (fd, optval,
1488 result);
1489 if (result != TARGET_NATIVE_OK)
1491 JCL_ThrowException (env, SOCKET_EXCEPTION,
1492 TARGET_NATIVE_LAST_ERROR_STRING ());
1493 return (0);
1496 if (optval)
1497 return (_javanet_create_boolean (env, JNI_TRUE));
1498 else
1499 return (_javanet_create_boolean (env, JNI_FALSE));
1501 break;
1503 case SOCKOPT_SO_KEEPALIVE:
1504 TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_KEEP_ALIVE (fd, optval, result);
1505 if (result != TARGET_NATIVE_OK)
1507 JCL_ThrowException (env, SOCKET_EXCEPTION,
1508 TARGET_NATIVE_LAST_ERROR_STRING ());
1509 return (0);
1512 if (optval)
1513 return (_javanet_create_boolean (env, JNI_TRUE));
1514 else
1515 return (_javanet_create_boolean (env, JNI_FALSE));
1517 break;
1519 default:
1520 JCL_ThrowException (env, SOCKET_EXCEPTION, "No such option");
1521 return (0);
1524 return (0);
1525 #else /* not WITHOUT_NETWORK */
1526 #endif /* not WITHOUT_NETWORK */
1529 void
1530 _javanet_shutdownInput (JNIEnv * env, jobject this)
1532 int fd;
1534 assert (env != NULL);
1535 assert ((*env) != NULL);
1537 /* Get the real file descriptor. */
1538 fd = _javanet_get_int_field (env, this, "native_fd");
1539 if (fd == -1)
1541 JCL_ThrowException (env, SOCKET_EXCEPTION,
1542 "Internal error: _javanet_get_option(): no native file descriptor");
1543 return;
1546 /* Shutdown input stream of socket. */
1547 if (shutdown (fd, SHUT_RD) == -1)
1549 JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
1550 return;
1554 void
1555 _javanet_shutdownOutput (JNIEnv * env, jobject this)
1557 int fd;
1559 assert (env != NULL);
1560 assert ((*env) != NULL);
1562 /* Get the real file descriptor. */
1563 fd = _javanet_get_int_field (env, this, "native_fd");
1564 if (fd == -1)
1566 JCL_ThrowException (env, SOCKET_EXCEPTION,
1567 "Internal error: _javanet_get_option(): no native file descriptor");
1568 return;
1571 /* Shutdown output stream of socket. */
1572 if (shutdown (fd, SHUT_WR) == -1)
1574 JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
1575 return;
1579 /* end of file */