summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/native/jni/java-net
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/native/jni/java-net')
-rw-r--r--libjava/classpath/native/jni/java-net/.cvsignore8
-rw-r--r--libjava/classpath/native/jni/java-net/Makefile.am14
-rw-r--r--libjava/classpath/native/jni/java-net/gnu_java_net_PlainDatagramSocketImpl.c452
-rw-r--r--libjava/classpath/native/jni/java-net/gnu_java_net_PlainSocketImpl.c320
-rw-r--r--libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c282
-rw-r--r--libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c66
-rw-r--r--libjava/classpath/native/jni/java-net/javanet.c1577
-rw-r--r--libjava/classpath/native/jni/java-net/javanet.h109
8 files changed, 2828 insertions, 0 deletions
diff --git a/libjava/classpath/native/jni/java-net/.cvsignore b/libjava/classpath/native/jni/java-net/.cvsignore
new file mode 100644
index 00000000000..e9f2658a694
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/.cvsignore
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/libjava/classpath/native/jni/java-net/Makefile.am b/libjava/classpath/native/jni/java-net/Makefile.am
new file mode 100644
index 00000000000..3e8c863a9a9
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/Makefile.am
@@ -0,0 +1,14 @@
+pkglib_LTLIBRARIES = libjavanet.la
+
+libjavanet_la_SOURCES = javanet.c \
+ javanet.h \
+ java_net_VMInetAddress.c \
+ java_net_VMNetworkInterface.c \
+ gnu_java_net_PlainDatagramSocketImpl.c \
+ gnu_java_net_PlainSocketImpl.c
+
+libjavanet_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo
+
+AM_LDFLAGS = @CLASSPATH_MODULE@
+AM_CPPFLAGS = @CLASSPATH_INCLUDES@
+AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@
diff --git a/libjava/classpath/native/jni/java-net/gnu_java_net_PlainDatagramSocketImpl.c b/libjava/classpath/native/jni/java-net/gnu_java_net_PlainDatagramSocketImpl.c
new file mode 100644
index 00000000000..5bc284f6426
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/gnu_java_net_PlainDatagramSocketImpl.c
@@ -0,0 +1,452 @@
+/* PlainDatagramSocketImpl.c - Native methods for PlainDatagramSocketImpl class
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "javanet.h"
+
+#include "target_native.h"
+#ifndef WITHOUT_NETWORK
+#include "target_native_network.h"
+#endif /* WITHOUT_NETWORK */
+
+#include "gnu_java_net_PlainDatagramSocketImpl.h"
+
+/*
+ * Note that most of the functions in this module simply redirect to another
+ * internal function. Why? Because many of these functions are shared
+ * with PlainSocketImpl.
+ */
+
+/*************************************************************************/
+
+/*
+ * Creates a new datagram socket
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_create (JNIEnv * env, jobject obj)
+{
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+#ifndef WITHOUT_NETWORK
+ _javanet_create (env, obj, 0);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Close the socket.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_close (JNIEnv * env, jobject obj)
+{
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+#ifndef WITHOUT_NETWORK
+ _javanet_close (env, obj, 0);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method binds the specified address to the specified local port.
+ * Note that we have to set the local address and local port public instance
+ * variables.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_bind (JNIEnv * env, jobject obj,
+ jint port, jobject addr)
+{
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+#ifndef WITHOUT_NETWORK
+ _javanet_bind (env, obj, addr, port, 0);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method sets the specified option for a socket
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_setOption (JNIEnv * env,
+ jobject obj,
+ jint option_id,
+ jobject val)
+{
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+#ifndef WITHOUT_NETWORK
+ _javanet_set_option (env, obj, option_id, val);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method sets the specified option for a socket
+ */
+JNIEXPORT jobject JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_getOption (JNIEnv * env,
+ jobject obj,
+ jint option_id)
+{
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+#ifndef WITHOUT_NETWORK
+ return (_javanet_get_option (env, obj, option_id));
+#else /* not WITHOUT_NETWORK */
+ return NULL;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Reads a buffer from a remote host
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_receive0 (JNIEnv * env, jobject obj,
+ jobject packet)
+{
+#ifndef WITHOUT_NETWORK
+ int addr, port, bytes_read;
+ unsigned int maxlen, offset;
+ jclass cls, addr_cls;
+ jfieldID fid;
+ jmethodID mid;
+ jarray arr;
+ unsigned char octets[4];
+ char ip_str[16];
+ jobject ip_str_obj, addr_obj;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ addr = 0;
+ port = 0;
+ maxlen = 0;
+ offset = 0;
+ bytes_read = 0;
+
+ if (packet == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/NullPointerException",
+ "Null datagram packet");
+ return;
+ }
+
+ /* Get the buffer from the packet */
+ cls = (*env)->GetObjectClass (env, packet);
+ if (cls == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error");
+ return;
+ }
+
+ mid = (*env)->GetMethodID (env, cls, "getData", "()[B");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: getData");
+ return;
+ }
+
+ arr = (*env)->CallObjectMethod (env, packet, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+ if (arr == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: call getData");
+ return;
+ }
+
+ /* Now get the offset from the packet */
+ mid = (*env)->GetMethodID (env, cls, "getOffset", "()I");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: getOffset");
+ return;
+ }
+
+ offset = (*env)->CallIntMethod (env, packet, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.receive(): Got the offset\n");
+
+ /* Now get the maximal available length from the packet */
+ fid = (*env)->GetFieldID (env, cls, "maxlen", "I");
+ if (fid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: maxlen");
+ return;
+ }
+
+ maxlen = (*env)->GetIntField (env, packet, fid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ /* Receive the packet */
+ /* should we try some sort of validation on the length? */
+ bytes_read =
+ _javanet_recvfrom (env, obj, arr, offset, maxlen, &addr, &port);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+ if (bytes_read == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: receive");
+ return;
+ }
+
+ DBG ("PlainDatagramSocketImpl.receive(): Received packet\n");
+
+ /* Store the address */
+ TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES (addr,
+ octets[0],
+ octets[1],
+ octets[2], octets[3]);
+ sprintf (ip_str, "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]);
+ ip_str_obj = (*env)->NewStringUTF (env, ip_str);
+ if (ip_str_obj == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: new string");
+ return;
+ }
+
+ addr_cls = (*env)->FindClass (env, "java/net/InetAddress");
+ if (addr_cls == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: InetAddress class");
+ return;
+ }
+ DBG ("PlainDatagramSocketImpl.receive(): Found InetAddress class\n");
+
+ mid = (*env)->GetStaticMethodID (env, addr_cls, "getByName",
+ "(Ljava/lang/String;)Ljava/net/InetAddress;");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal Error");
+ return;
+ }
+ DBG
+ ("PlainDatagramSocketImpl.receive(): Found InetAddress.getByName method\n");
+
+ addr_obj = (*env)->CallStaticObjectMethod (env, addr_cls, mid, ip_str_obj);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ mid = (*env)->GetMethodID (env, cls, "setAddress",
+ "(Ljava/net/InetAddress;)V");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: setAddress");
+ return;
+ }
+
+ (*env)->CallVoidMethod (env, packet, mid, addr_obj);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.receive(): Stored the address\n");
+
+ /* Store the port */
+ mid = (*env)->GetMethodID (env, cls, "setPort", "(I)V");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: setPort");
+ return;
+ }
+
+ (*env)->CallVoidMethod (env, packet, mid, port);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.receive(): Stored the port\n");
+
+ /* Store back the length */
+ fid = (*env)->GetFieldID (env, cls, "length", "I");
+ if (fid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal error: length");
+ return;
+ }
+
+ (*env)->SetIntField (env, packet, fid, bytes_read);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.receive(): Stored the length\n");
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Writes a buffer to the remote host
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_sendto (JNIEnv * env, jobject obj,
+ jobject addr, jint port,
+ jarray buf, jint offset,
+ jint len)
+{
+#ifndef WITHOUT_NETWORK
+ jint netAddress;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ netAddress = _javanet_get_netaddr (env, addr);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.sendto(): have addr\n");
+
+ _javanet_sendto (env, obj, buf, offset, len, netAddress, port);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.sendto(): finished\n");
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Joins a multicast group
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_join (JNIEnv * env, jobject obj,
+ jobject addr)
+{
+#ifndef WITHOUT_NETWORK
+ jint netAddress;
+ int fd;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ netAddress = _javanet_get_netaddr (env, addr);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ fd = _javanet_get_int_field (env, obj, "native_fd");
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.join(): have native fd\n");
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_ADD_MEMBERSHIP (fd, netAddress,
+ result);
+
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+
+ DBG ("PlainDatagramSocketImpl.join(): finished\n");
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Leaves a multicast group
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainDatagramSocketImpl_leave (JNIEnv * env, jobject obj,
+ jobject addr)
+{
+#ifndef WITHOUT_NETWORK
+ jint netAddress;
+ int fd;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ netAddress = _javanet_get_netaddr (env, addr);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ fd = _javanet_get_int_field (env, obj, "native_fd");
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ DBG ("PlainDatagramSocketImpl.leave(): have native fd\n");
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_DROP_MEMBERSHIP (fd, netAddress,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+
+ DBG ("PlainDatagramSocketImpl.leave(): finished\n");
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
diff --git a/libjava/classpath/native/jni/java-net/gnu_java_net_PlainSocketImpl.c b/libjava/classpath/native/jni/java-net/gnu_java_net_PlainSocketImpl.c
new file mode 100644
index 00000000000..a5261514dce
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/gnu_java_net_PlainSocketImpl.c
@@ -0,0 +1,320 @@
+/* PlainSocketImpl.c - Native methods for PlainSocketImpl class
+ Copyright (C) 1998, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "javanet.h"
+
+#include "target_native.h"
+#ifndef WITHOUT_NETWORK
+#include "target_native_network.h"
+#endif /* WITHOUT_NETWORK */
+
+#include "gnu_java_net_PlainSocketImpl.h"
+
+/*
+ * Note that the functions in this module simply redirect to another
+ * internal function. Why? Because many of these functions are shared
+ * with PlainDatagramSocketImpl. The unshared ones were done the same
+ * way for consistency.
+ */
+
+/*************************************************************************/
+
+/*
+ * Creates a new stream or datagram socket
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_create (JNIEnv * env, jobject this,
+ jboolean stream)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_create (env, this, stream);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Close the socket. Any underlying streams will be closed by this
+ * action as well.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_close (JNIEnv * env, jobject this)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_close (env, this, 1);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Connects to the specified destination.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_connect (JNIEnv * env, jobject this,
+ jobject addr, jint port)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_connect (env, this, addr, port);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method binds the specified address to the specified local port.
+ * Note that we have to set the local address and local port public instance
+ * variables.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_bind (JNIEnv * env, jobject this,
+ jobject addr, jint port)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_bind (env, this, addr, port, 1);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Starts listening on a socket with the specified number of pending
+ * connections allowed.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_listen (JNIEnv * env, jobject this,
+ jint queuelen)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_listen (env, this, queuelen);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Accepts a new connection and assigns it to the passed in SocketImpl
+ * object. Note that we assume this is a PlainSocketImpl just like us.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_accept (JNIEnv * env, jobject this,
+ jobject impl)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_accept (env, this, impl);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_net_PlainSocketImpl_available (JNIEnv * env, jobject this)
+{
+#ifndef WITHOUT_NETWORK
+ jclass cls;
+ jfieldID fid;
+ int fd;
+ int bytesAvailable;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ cls = (*env)->GetObjectClass (env, this);
+ if (cls == 0)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "internal error");
+ return 0;
+ }
+
+ fid = (*env)->GetFieldID (env, cls, "native_fd", "I");
+ if (fid == 0)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "internal error");
+ return 0;
+ }
+
+ fd = (*env)->GetIntField (env, this, fid);
+
+ TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_AVAILABLE (fd, bytesAvailable, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return 0;
+ }
+
+ return bytesAvailable;
+#else /* not WITHOUT_NETWORK */
+ return 0;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method sets the specified option for a socket
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_setOption (JNIEnv * env, jobject this,
+ jint option_id, jobject val)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_set_option (env, this, option_id, val);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method sets the specified option for a socket
+ */
+JNIEXPORT jobject JNICALL
+Java_gnu_java_net_PlainSocketImpl_getOption (JNIEnv * env, jobject this,
+ jint option_id)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ return (_javanet_get_option (env, this, option_id));
+#else /* not WITHOUT_NETWORK */
+ return NULL;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Reads a buffer from a remote host
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_net_PlainSocketImpl_read (JNIEnv * env, jobject this,
+ jarray buf, jint offset, jint len)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ return (_javanet_recvfrom (env, this, buf, offset, len, 0, 0));
+#else /* not WITHOUT_NETWORK */
+ return 0;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Writes a buffer to the remote host
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_write (JNIEnv * env, jobject this,
+ jarray buf, jint offset, jint len)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_sendto (env, this, buf, offset, len, 0, 0);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_shutdownInput (JNIEnv * env, jobject this)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_shutdownInput (env, this);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_net_PlainSocketImpl_shutdownOutput (JNIEnv * env, jobject this)
+{
+#ifndef WITHOUT_NETWORK
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ _javanet_shutdownOutput (env, this);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/* end of file */
diff --git a/libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c b/libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c
new file mode 100644
index 00000000000..d33265cff7e
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c
@@ -0,0 +1,282 @@
+/* VMInetAddress.c - Native methods for InetAddress class
+ Copyright (C) 1998, 2002, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "javanet.h"
+
+#include "target_native.h"
+#ifndef WITHOUT_NETWORK
+#include "target_native_network.h"
+#endif /* WITHOUT_NETWORK */
+
+#include "java_net_VMInetAddress.h"
+
+/*************************************************************************/
+
+/*
+ * Function to return the local hostname
+ */
+JNIEXPORT jstring JNICALL
+Java_java_net_VMInetAddress_getLocalHostname (JNIEnv * env,
+ jclass class
+ __attribute__ ((__unused__)))
+{
+ char hostname[256];
+ int result;
+ jstring retval;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+#ifndef WITHOUT_NETWORK
+ TARGET_NATIVE_NETWORK_GET_HOSTNAME (hostname, sizeof (hostname), result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ strcpy (hostname, "localhost");
+ }
+#else /* not WITHOUT_NETWORK */
+ strcpy (hostname, "localhost");
+#endif /* not WITHOUT_NETWORK */
+
+ retval = (*env)->NewStringUTF (env, hostname);
+
+ return (retval);
+}
+
+/*************************************************************************/
+
+/*
+ * Returns the value of the special IP address INADDR_ANY
+ */
+JNIEXPORT jarray JNICALL
+Java_java_net_VMInetAddress_lookupInaddrAny (JNIEnv * env,
+ jclass class
+ __attribute__ ((__unused__)))
+{
+ jarray IParray;
+ jbyte *octets;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Allocate an array for the IP address */
+ IParray = (*env)->NewByteArray (env, 4);
+ if (IParray == NULL)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ return (jarray) NULL;
+ }
+
+ /* Copy in the values */
+ octets = (*env)->GetByteArrayElements (env, IParray, 0);
+
+#ifndef WITHOUT_NETWORK
+ TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES (INADDR_ANY,
+ octets[0],
+ octets[1],
+ octets[2], octets[3]);
+ (*env)->ReleaseByteArrayElements (env, IParray, octets, 0);
+#else /* not WITHOUT_NETWORK */
+ octets[0] = 0;
+ octets[1] = 0;
+ octets[2] = 0;
+ octets[3] = 0;
+#endif /* not WITHOUT_NETWORK */
+
+ return (IParray);
+}
+
+/*************************************************************************/
+
+/*
+ * Function to return the canonical hostname for a given IP address passed
+ * in as a byte array
+ */
+JNIEXPORT jstring JNICALL
+Java_java_net_VMInetAddress_getHostByAddr (JNIEnv * env,
+ jclass class
+ __attribute__ ((__unused__)),
+ jarray arr)
+{
+#ifndef WITHOUT_NETWORK
+ jbyte *octets;
+ jsize len;
+ int addr;
+ char hostname[255];
+ int result;
+ jstring retval;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Grab the byte[] array with the IP out of the input data */
+ len = (*env)->GetArrayLength (env, arr);
+ if (len != 4)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
+ return (jstring) NULL;
+ }
+
+ octets = (*env)->GetByteArrayElements (env, arr, 0);
+ if (!octets)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
+ return (jstring) NULL;
+ }
+
+ /* Convert it to a 32 bit address */
+ TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT (octets[0],
+ octets[1],
+ octets[2], octets[3], addr);
+
+ /* Release some memory */
+ (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
+
+ /* Resolve the address and return the name */
+ TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_ADDRESS (addr, hostname,
+ sizeof (hostname), result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP address");
+ return (jstring) NULL;
+ }
+
+ retval = (*env)->NewStringUTF (env, hostname);
+
+ return (retval);
+#else /* not WITHOUT_NETWORK */
+ return (jstring) NULL;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+JNIEXPORT jobjectArray JNICALL
+Java_java_net_VMInetAddress_getHostByName (JNIEnv * env,
+ jclass class
+ __attribute__ ((__unused__)),
+ jstring host)
+{
+#ifndef WITHOUT_NETWORK
+ const char *hostname;
+/* FIXME: limitation of max. 64 addresses - how to make it more flexibale? */
+ int addresses[64];
+ jsize addresses_count;
+ int result;
+ jclass arr_class;
+ jobjectArray addrs;
+ int i;
+ jbyte *octets;
+ jarray ret_octets;
+ int max_addresses;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Grab the hostname string */
+ hostname = (*env)->GetStringUTFChars (env, host, 0);
+ if (!hostname)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Null hostname");
+ return (jobjectArray) NULL;
+ }
+
+ max_addresses = sizeof (addresses) / sizeof (addresses[0]);
+ TARGET_NATIVE_NETWORK_GET_HOSTNAME_BY_NAME (hostname,
+ addresses,
+ max_addresses,
+ addresses_count, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, (char *) hostname);
+ return (jobjectArray) NULL;
+ }
+ (*env)->ReleaseStringUTFChars (env, host, hostname);
+
+ arr_class = (*env)->FindClass (env, "[B");
+ if (!arr_class)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ return (jobjectArray) NULL;
+ }
+
+ addrs = (*env)->NewObjectArray (env, addresses_count, arr_class, 0);
+ if (!addrs)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ return (jobjectArray) NULL;
+ }
+
+ /* Now loop and copy in each address */
+ for (i = 0; i < addresses_count; i++)
+ {
+ ret_octets = (*env)->NewByteArray (env, 4);
+ if (!ret_octets)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ return (jobjectArray) NULL;
+ }
+
+ octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
+
+ TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES (addresses[i],
+ octets[0],
+ octets[1],
+ octets[2], octets[3]);
+
+ (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
+
+ (*env)->SetObjectArrayElement (env, addrs, i, ret_octets);
+ }
+
+ return (addrs);
+#else /* not WITHOUT_NETWORK */
+ return (jobjectArray) NULL;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/* end of file */
diff --git a/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c b/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c
new file mode 100644
index 00000000000..71f5e8927e5
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c
@@ -0,0 +1,66 @@
+/* VMNetworkInterface.c - Native methods for NetworkInterface class
+ Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "java_net_VMNetworkInterface.h"
+
+#include "javanet.h"
+
+/*
+ * Returns all local network interfaces as vector
+ */
+JNIEXPORT jobject JNICALL
+Java_java_net_VMNetworkInterface_getInterfaces (JNIEnv * env,
+ jclass class
+ __attribute__ ((__unused__)))
+{
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "java.net.VMNetworkInterface.getInterfaces(): not implemented");
+ return 0;
+}
+
+/* end of file */
diff --git a/libjava/classpath/native/jni/java-net/javanet.c b/libjava/classpath/native/jni/java-net/javanet.c
new file mode 100644
index 00000000000..fdc1c22ecbf
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/javanet.c
@@ -0,0 +1,1577 @@
+/* javanet.c - Common internal functions for the java.net package
+ Copyright (C) 1998, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+/* do not move; needed here because of some macro definitions */
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <jni.h>
+#include <jcl.h>
+
+#include "javanet.h"
+
+#include "target_native.h"
+#ifndef WITHOUT_NETWORK
+#include "target_native_network.h"
+#endif /* WITHOUT_NETWORK */
+
+#ifndef WITHOUT_NETWORK
+/* Need to have some value for SO_TIMEOUT */
+#ifndef SO_TIMEOUT
+#ifndef SO_RCVTIMEO
+#warning Neither SO_TIMEOUT or SO_RCVTIMEO are defined!
+#warning This will cause all get/setOption calls with that value to throw an exception
+#else
+#define SO_TIMEOUT SO_RCVTIMEO
+#endif /* not SO_RCVTIMEO */
+#endif /* not SO_TIMEOUT */
+#endif /* WITHOUT_NETWORK */
+
+/*************************************************************************/
+
+/*
+ * Sets an integer field in the specified object.
+ */
+static void
+_javanet_set_int_field (JNIEnv * env, jobject obj,
+ const char *class, const char *field, int val)
+{
+ jclass cls;
+ jfieldID fid;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ cls = (*env)->FindClass (env, class);
+ if (cls == NULL)
+ return;
+
+ fid = (*env)->GetFieldID (env, cls, field, "I");
+ if (fid == NULL)
+ return;
+
+ (*env)->SetIntField (env, obj, fid, val);
+
+ return;
+}
+
+/*************************************************************************/
+
+/*
+ * Returns the value of the specified integer instance variable field or
+ * -1 if an error occurs.
+ */
+int
+_javanet_get_int_field (JNIEnv * env, jobject obj, const char *field)
+{
+ jclass cls = 0;
+ jfieldID fid;
+ int fd;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_get_int_field(): Entered _javanet_get_int_field\n");
+
+ cls = (*env)->GetObjectClass (env, obj);
+ if (cls == NULL)
+ return -1;
+
+ fid = (*env)->GetFieldID (env, cls, field, "I");
+ if (fid == NULL)
+ return -1;
+ DBG ("_javanet_get_int_field(): Found field id\n");
+
+ fd = (*env)->GetIntField (env, obj, fid);
+
+ return fd;
+}
+
+/*************************************************************************/
+
+/*
+ * Creates a FileDescriptor object in the parent class. It is not used
+ * by this implementation, but the docs list it as a variable, so we
+ * need to include it.
+ */
+static void
+_javanet_create_localfd (JNIEnv * env, jobject this)
+{
+ jclass this_cls, fd_cls;
+ jfieldID fid;
+ jmethodID mid;
+ jobject fd_obj;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_create_localfd(): Entered _javanet_create_localfd\n");
+
+ /* Look up the fd field */
+ this_cls = (*env)->FindClass (env, "java/net/SocketImpl");
+ if (this_cls == NULL)
+ return;
+
+ fid = (*env)->GetFieldID (env, this_cls, "fd", "Ljava/io/FileDescriptor;");
+ if (fid == NULL)
+ return;
+
+ DBG ("_javanet_create_localfd(): Found fd variable\n");
+
+ /* Create a FileDescriptor */
+ fd_cls = (*env)->FindClass (env, "java/io/FileDescriptor");
+ if (fd_cls == NULL)
+ return;
+
+ DBG ("_javanet_create_localfd(): Found FileDescriptor class\n");
+
+ mid = (*env)->GetMethodID (env, fd_cls, "<init>", "()V");
+ if (mid == NULL)
+ return;
+
+ DBG ("_javanet_create_localfd(): Found FileDescriptor constructor\n");
+
+ fd_obj = (*env)->NewObject (env, fd_cls, mid);
+ if (fd_obj == NULL)
+ return;
+
+ DBG ("_javanet_create_localfd(): Created FileDescriptor\n");
+
+ /* Now set the pointer to the new FileDescriptor */
+ (*env)->SetObjectField (env, this, fid, fd_obj);
+ DBG ("_javanet_create_localfd(): Set fd field\n");
+
+ return;
+}
+
+/*************************************************************************/
+
+/*
+ * Returns a Boolean object with the specfied value
+ */
+static jobject
+_javanet_create_boolean (JNIEnv * env, jboolean val)
+{
+ jclass cls;
+ jmethodID mid;
+ jobject obj;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ cls = (*env)->FindClass (env, "java/lang/Boolean");
+ if (cls == NULL)
+ return NULL;
+
+ mid = (*env)->GetMethodID (env, cls, "<init>", "(Z)V");
+ if (mid == NULL)
+ return NULL;
+
+ obj = (*env)->NewObject (env, cls, mid, val);
+ if (obj == NULL)
+ return NULL;
+
+ return obj;
+}
+
+/*************************************************************************/
+
+/*
+ * Returns an Integer object with the specfied value
+ */
+static jobject
+_javanet_create_integer (JNIEnv * env, jint val)
+{
+ jclass cls;
+ jmethodID mid;
+ jobject obj;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ cls = (*env)->FindClass (env, "java/lang/Integer");
+ if (cls == NULL)
+ return NULL;
+
+ mid = (*env)->GetMethodID (env, cls, "<init>", "(I)V");
+ if (mid == NULL)
+ return NULL;
+
+ obj = (*env)->NewObject (env, cls, mid, val);
+ if (obj == NULL)
+ return NULL;
+
+ return obj;
+}
+
+/*************************************************************************/
+
+/*
+ * Builds an InetAddress object from a 32 bit address in host byte order
+ */
+static jobject
+_javanet_create_inetaddress (JNIEnv * env, int netaddr)
+{
+#ifndef WITHOUT_NETWORK
+ unsigned char octets[4];
+ char buf[16];
+ jclass ia_cls;
+ jmethodID mid;
+ jstring ip_str;
+ jobject ia;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Build a string IP address */
+ TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES (netaddr,
+ octets[0],
+ octets[1],
+ octets[2], octets[3]);
+ sprintf (buf, "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]);
+ DBG ("_javanet_create_inetaddress(): Created ip addr string\n");
+
+ /* Get an InetAddress object for this IP */
+ ia_cls = (*env)->FindClass (env, "java/net/InetAddress");
+ if (ia_cls == NULL)
+ {
+ return NULL;
+ }
+
+ DBG ("_javanet_create_inetaddress(): Found InetAddress class\n");
+
+ mid = (*env)->GetStaticMethodID (env, ia_cls, "getByName",
+ "(Ljava/lang/String;)Ljava/net/InetAddress;");
+ if (mid == NULL)
+ {
+ return NULL;
+ }
+
+ DBG ("_javanet_create_inetaddress(): Found getByName method\n");
+
+ ip_str = (*env)->NewStringUTF (env, buf);
+ if (ip_str == NULL)
+ {
+ return NULL;
+ }
+
+ ia = (*env)->CallStaticObjectMethod (env, ia_cls, mid, ip_str);
+ if (ia == NULL)
+ {
+ return NULL;
+ }
+
+ DBG ("_javanet_create_inetaddress(): Called getByName method\n");
+
+ return ia;
+#else /* not WITHOUT_NETWORK */
+ return NULL;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+static void
+_javanet_set_remhost_addr (JNIEnv * env, jobject this, jobject ia)
+{
+ jclass this_cls;
+ jfieldID fid;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Set the variable in the object */
+ this_cls = (*env)->FindClass (env, "java/net/SocketImpl");
+ if (this_cls == NULL)
+ return;
+
+ fid =
+ (*env)->GetFieldID (env, this_cls, "address", "Ljava/net/InetAddress;");
+ if (fid == NULL)
+ return;
+
+ DBG ("_javanet_set_remhost_addr(): Found address field\n");
+
+ (*env)->SetObjectField (env, this, fid, ia);
+ DBG ("_javanet_set_remhost_addr(): Set field\n");
+}
+
+/*
+ * Set's the value of the "addr" field in PlainSocketImpl with a new
+ * InetAddress for the specified addr
+ */
+static void
+_javanet_set_remhost (JNIEnv * env, jobject this, int netaddr)
+{
+ jobject ia;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_set_remhost(): Entered _javanet_set_remhost\n");
+
+ /* Get an InetAddress object */
+ ia = _javanet_create_inetaddress (env, netaddr);
+ if (ia == NULL)
+ return;
+
+ _javanet_set_remhost_addr (env, this, ia);
+}
+
+
+/*************************************************************************/
+
+/*
+ * Returns a 32 bit Internet address for the passed in InetAddress object
+ */
+int
+_javanet_get_netaddr (JNIEnv * env, jobject addr)
+{
+#ifndef WITHOUT_NETWORK
+ jclass cls = 0;
+ jmethodID mid;
+ jarray arr = 0;
+ jbyte *octets;
+ int netaddr, len;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_get_netaddr(): Entered _javanet_get_netaddr\n");
+
+ if (addr == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/NullPointerException",
+ "Null address");
+ return 0;
+ }
+
+ /* Call the getAddress method on the object to retrieve the IP address */
+ cls = (*env)->GetObjectClass (env, addr);
+ if (cls == NULL)
+ return 0;
+
+ mid = (*env)->GetMethodID (env, cls, "getAddress", "()[B");
+ if (mid == NULL)
+ return 0;
+
+ DBG ("_javanet_get_netaddr(): Got getAddress method\n");
+
+ arr = (*env)->CallObjectMethod (env, addr, mid);
+ if (arr == NULL)
+ return 0;
+
+ DBG ("_javanet_get_netaddr(): Got the address\n");
+
+ /* Turn the IP address into a 32 bit Internet address in network byte order */
+ len = (*env)->GetArrayLength (env, arr);
+ if (len != 4)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal Error");
+ return 0;
+ }
+ DBG ("_javanet_get_netaddr(): Length ok\n");
+
+ octets = (*env)->GetByteArrayElements (env, arr, 0);
+ if (octets == NULL)
+ return 0;
+
+ DBG ("_javanet_get_netaddr(): Grabbed bytes\n");
+
+ TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT (octets[0],
+ octets[1],
+ octets[2],
+ octets[3], netaddr);
+
+ (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
+ DBG ("_javanet_get_netaddr(): Done getting addr\n");
+
+ return netaddr;
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Creates a new stream or datagram socket
+ */
+void
+_javanet_create (JNIEnv * env, jobject this, jboolean stream)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ if (stream)
+ {
+ /* create a stream socket */
+ TARGET_NATIVE_NETWORK_SOCKET_OPEN_STREAM (fd, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+ }
+ else
+ {
+ /* create a datagram socket, set broadcast option */
+ TARGET_NATIVE_NETWORK_SOCKET_OPEN_DATAGRAM (fd, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_BROADCAST (fd, 1, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+ }
+
+ if (stream)
+ _javanet_set_int_field (env, this, "gnu/java/net/PlainSocketImpl",
+ "native_fd", fd);
+ else
+ _javanet_set_int_field (env, this, "gnu/java/net/PlainDatagramSocketImpl",
+ "native_fd", fd);
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* Try to make sure we close the socket since close() won't work. */
+ do
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ if (result != TARGET_NATIVE_OK
+ && (TARGET_NATIVE_LAST_ERROR ()
+ != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
+ return;
+ }
+ while (result != TARGET_NATIVE_OK);
+ return;
+ }
+
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Close the socket. Any underlying streams will be closed by this
+ * action as well.
+ */
+void
+_javanet_close (JNIEnv * env, jobject this, int stream)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ int result;
+ int error = 0;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ return;
+
+ if (stream)
+ _javanet_set_int_field (env, this, "gnu/java/net/PlainSocketImpl",
+ "native_fd", -1);
+ else
+ _javanet_set_int_field (env, this, "gnu/java/net/PlainDatagramSocketImpl",
+ "native_fd", -1);
+ do
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ /* Only throw an error when a "real" error occurs. */
+ error = TARGET_NATIVE_LAST_ERROR ();
+ if (error != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL
+ && error != ENOTCONN && error != ECONNRESET && error != EBADF)
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ }
+ }
+ while (error == TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL);
+
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Connects to the specified destination.
+ */
+void
+_javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port)
+{
+#ifndef WITHOUT_NETWORK
+ int netaddr, fd;
+ int result;
+ int local_address, local_port;
+ int remote_address, remote_port;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_connect(): Entered _javanet_connect\n");
+
+ /* Pre-process input variables */
+ netaddr = _javanet_get_netaddr (env, addr);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ if (port == -1)
+ port = 0;
+ DBG ("_javanet_connect(): Got network address\n");
+
+ /* Grab the real socket file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_connect(): no native file descriptor");
+ return;
+ }
+ DBG ("_javanet_connect(): Got native fd\n");
+
+ /* Connect up */
+ do
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_CONNECT (fd, netaddr, port, result);
+ if (result != TARGET_NATIVE_OK
+ && (TARGET_NATIVE_LAST_ERROR ()
+ != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+ }
+ while (result != TARGET_NATIVE_OK);
+
+ DBG ("_javanet_connect(): Connected successfully\n");
+
+ /* Populate instance variables */
+ TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (fd, local_address, local_port,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ return;
+ }
+
+ _javanet_create_localfd (env, this);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ return;
+ }
+ DBG ("_javanet_connect(): Created fd\n");
+
+ _javanet_set_int_field (env, this, "java/net/SocketImpl", "localport",
+ local_port);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ return;
+ }
+ DBG ("_javanet_connect(): Set the local port\n");
+
+ TARGET_NATIVE_NETWORK_SOCKET_GET_REMOTE_INFO (fd, remote_address,
+ remote_port, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ return;
+ }
+
+ if (remote_address == netaddr)
+ {
+ _javanet_set_remhost_addr (env, this, addr);
+ }
+ else
+ {
+ _javanet_set_remhost (env, this, remote_address);
+ }
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ return;
+ }
+ DBG ("_javanet_connect(): Set the remote host\n");
+
+ _javanet_set_int_field (env, this, "java/net/SocketImpl", "port",
+ remote_port);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ return;
+ }
+ DBG ("_javanet_connect(): Set the remote port\n");
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * This method binds the specified address to the specified local port.
+ * Note that we have to set the local address and local
+ * port public instance variables.
+ */
+void
+_javanet_bind (JNIEnv * env, jobject this, jobject addr, jint port,
+ int stream)
+{
+#ifndef WITHOUT_NETWORK
+ jclass cls;
+ jmethodID mid;
+ jbyteArray arr = 0;
+ jbyte *octets;
+ jint fd;
+ int tmpaddr;
+ int result;
+ int local_address, local_port;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_bind(): Entering native bind()\n");
+
+ /* Get the address to connect to */
+ cls = (*env)->GetObjectClass (env, addr);
+ if (cls == NULL)
+ return;
+
+ mid = (*env)->GetMethodID (env, cls, "getAddress", "()[B");
+ if (mid == NULL)
+ return;
+
+ DBG ("_javanet_bind(): Past getAddress method id\n");
+
+ arr = (*env)->CallObjectMethod (env, addr, mid);
+ if ((arr == NULL) || (*env)->ExceptionOccurred (env))
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_bind()");
+ return;
+ }
+
+ DBG ("_javanet_bind(): Past call object method\n");
+
+ octets = (*env)->GetByteArrayElements (env, arr, 0);
+ if (octets == NULL)
+ return;
+
+ DBG ("_javanet_bind(): Past grab array\n");
+
+ /* Get the native socket file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_bind(): no native file descriptor");
+ return;
+ }
+ DBG ("_javanet_bind(): Past native_fd lookup\n");
+
+ /* XXX NYI ??? */
+ _javanet_set_option (env, this, SOCKOPT_SO_REUSEADDR,
+ _javanet_create_boolean (env, JNI_TRUE));
+
+
+ /* Bind the socket */
+ TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT (octets[0],
+ octets[1],
+ octets[2],
+ octets[3], tmpaddr);
+ TARGET_NATIVE_NETWORK_SOCKET_BIND (fd, tmpaddr, port, result);
+
+ if (result != TARGET_NATIVE_OK)
+ {
+ char *errorstr = TARGET_NATIVE_LAST_ERROR_STRING ();
+ (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
+
+ JCL_ThrowException (env, BIND_EXCEPTION,
+ errorstr);
+ return;
+ }
+ DBG ("_javanet_bind(): Past bind\n");
+
+ (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
+
+ /* Update instance variables, specifically the local port number */
+ TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (fd, local_address, local_port,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+
+ if (stream)
+ _javanet_set_int_field (env, this, "java/net/SocketImpl",
+ "localport", local_port);
+ else
+ _javanet_set_int_field (env, this, "java/net/DatagramSocketImpl",
+ "localPort", local_port);
+ DBG ("_javanet_bind(): Past update port number\n");
+
+ return;
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Starts listening on a socket with the specified number of pending
+ * connections allowed.
+ */
+void
+_javanet_listen (JNIEnv * env, jobject this, jint queuelen)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_listen(): no native file descriptor");
+ return;
+ }
+
+ /* Start listening */
+ TARGET_NATIVE_NETWORK_SOCKET_LISTEN (fd, queuelen, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Accepts a new connection and assigns it to the passed in SocketImpl
+ * object. Note that we assume this is a PlainSocketImpl just like us
+ */
+void
+_javanet_accept (JNIEnv * env, jobject this, jobject impl)
+{
+#ifndef WITHOUT_NETWORK
+ int fd, newfd;
+ int result;
+ int local_address, local_port;
+ int remote_address, remote_port;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_accept(): no native file descriptor");
+ return;
+ }
+
+ /* Accept the connection */
+ do
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_ACCEPT (fd, newfd, result);
+ if (result != TARGET_NATIVE_OK
+ && (TARGET_NATIVE_LAST_ERROR ()
+ != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_accept(): ");
+ return;
+ }
+ }
+ while (result != TARGET_NATIVE_OK);
+
+ /* Populate instance variables */
+ _javanet_set_int_field (env, impl, "gnu/java/net/PlainSocketImpl",
+ "native_fd", newfd);
+
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* Try to make sure we close the socket since close() won't work. */
+ do
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ if (result != TARGET_NATIVE_OK
+ && (TARGET_NATIVE_LAST_ERROR ()
+ != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL))
+ return;
+ }
+ while (result != TARGET_NATIVE_OK);
+ return;
+ }
+
+ TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (newfd, local_address,
+ local_port, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+
+ _javanet_create_localfd (env, impl);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ return;
+ }
+
+ _javanet_set_int_field (env, impl, "java/net/SocketImpl", "localport",
+ local_port);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ return;
+ }
+
+ TARGET_NATIVE_NETWORK_SOCKET_GET_REMOTE_INFO (newfd, remote_address,
+ remote_port, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ return;
+ }
+
+ _javanet_set_remhost (env, impl, remote_address);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ return;
+ }
+
+ _javanet_set_int_field (env, impl, "java/net/SocketImpl", "port",
+ remote_port);
+ if ((*env)->ExceptionOccurred (env))
+ {
+ /* We don't care whether this succeeds. close() will cleanup later. */
+ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ return;
+ }
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Receives a buffer from a remote host. The args are:
+ *
+ * buf - The byte array into which the data received will be written
+ * offset - Offset into the byte array to start writing
+ * len - The number of bytes to read.
+ * addr - Pointer to 32 bit net address of host to receive from. If null,
+ * this parm is ignored. If pointing to an address of 0, the
+ * actual address read is stored here
+ * port - Pointer to the port to receive from. If null, this parm is ignored.
+ * If it is 0, the actual remote port received from is stored here
+ *
+ * The actual number of bytes read is returned.
+ */
+int
+_javanet_recvfrom (JNIEnv * env, jobject this, jarray buf, int offset,
+ int len, int *addr, int *port)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ jbyte *p;
+ int from_address, from_port;
+ int received_bytes;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ DBG ("_javanet_recvfrom(): Entered _javanet_recvfrom\n");
+
+ /* Get the real file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_recvfrom(): no native file descriptor");
+ return 0;
+ }
+ DBG ("_javanet_recvfrom(): Got native_fd\n");
+
+ /* Get a pointer to the buffer */
+ p = (*env)->GetByteArrayElements (env, buf, 0);
+ if (p == NULL)
+ return 0;
+
+ DBG ("_javanet_recvfrom(): Got buffer\n");
+
+ /* Read the data */
+ from_address = 0;
+ from_port = 0;
+ do
+ {
+ if (addr != NULL)
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_WITH_ADDRESS_PORT (fd,
+ p + offset,
+ len,
+ from_address,
+ from_port,
+ received_bytes);
+ }
+ else
+ {
+ TARGET_NATIVE_NETWORK_SOCKET_RECEIVE (fd, p + offset, len,
+ received_bytes);
+ }
+ }
+ while ((received_bytes == -1) &&
+ (TARGET_NATIVE_LAST_ERROR () ==
+ TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL));
+
+ if (received_bytes == -1)
+ {
+ if (TARGET_NATIVE_LAST_ERROR () == EAGAIN)
+ JCL_ThrowException (env, "java/net/SocketTimeoutException", "Timeout");
+ else
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+
+ /* Cleanup and return. */
+ (*env)->ReleaseByteArrayElements (env, buf, p, 0);
+ return 0;
+ }
+
+ (*env)->ReleaseByteArrayElements (env, buf, p, 0);
+
+ /* Handle return addr case */
+ if (addr != NULL)
+ {
+ (*addr) = from_address;
+ if (port != NULL)
+ (*port) = from_port;
+ }
+
+ return (received_bytes);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Sends a buffer to a remote host. The args are:
+ *
+ * buf - A byte array
+ * offset - Index into the byte array to start sendign
+ * len - The number of bytes to write
+ * addr - The 32bit address to send to (may be 0)
+ * port - The port number to send to (may be 0)
+ */
+void
+_javanet_sendto (JNIEnv * env, jobject this, jarray buf, int offset, int len,
+ int addr, int port)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ jbyte *p;
+ int bytes_sent;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_sendto(): no native file descriptor");
+ return;
+ }
+
+ /* Get a pointer to the buffer */
+ p = (*env)->GetByteArrayElements (env, buf, 0);
+ if (p == NULL)
+ return;
+
+ /* We must send all the data, so repeat till done. */
+ while (len > 0)
+ {
+ /* Send the data */
+ if (addr == 0)
+ {
+ DBG ("_javanet_sendto(): Sending....\n");
+ TARGET_NATIVE_NETWORK_SOCKET_SEND (fd, p + offset, len, bytes_sent);
+ }
+ else
+ {
+ DBG ("_javanet_sendto(): Sending....\n");
+ TARGET_NATIVE_NETWORK_SOCKET_SEND_WITH_ADDRESS_PORT (fd, p + offset,
+ len, addr, port,
+ bytes_sent);
+ }
+
+ if (bytes_sent < 0)
+ {
+ if (TARGET_NATIVE_LAST_ERROR ()
+ != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ break;
+ }
+ }
+ else
+ {
+ len -= bytes_sent;
+ addr += bytes_sent;
+ }
+ }
+
+ (*env)->ReleaseByteArrayElements (env, buf, p, 0);
+
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Sets the specified option for a socket
+ */
+void
+_javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ int optval;
+ jclass cls;
+ jmethodID mid;
+ int address;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option(): no native file descriptor");
+ return;
+ }
+
+ /* We need a class object for all cases below */
+ cls = (*env)->GetObjectClass (env, val);
+ if (cls == NULL)
+ return;
+
+ /* Process the option request */
+ result = TARGET_NATIVE_ERROR;
+ switch (option_id)
+ {
+ /* TCP_NODELAY case. val is a Boolean that tells us what to do */
+ case SOCKOPT_TCP_NODELAY:
+ mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+ /* Should be a 0 or a 1 */
+ optval = (*env)->CallBooleanMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_TCP_NODELAY (fd, optval,
+ result);
+ break;
+
+ /* SO_LINGER case. If val is a boolean, then it will always be set
+ to false indicating disable linger, otherwise it will be an
+ integer that contains the linger value */
+ case SOCKOPT_SO_LINGER:
+ mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
+ if (mid)
+ {
+ /* We are disabling linger */
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_LINGER (fd, 1, 0,
+ result);
+ }
+ else
+ {
+ /* Clear exception if thrown for failure to do method lookup
+ above */
+ if ((*env)->ExceptionOccurred (env))
+ (*env)->ExceptionClear (env);
+
+ mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+ optval = (*env)->CallIntMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_LINGER (fd, 0, optval,
+ result);
+ }
+ break;
+
+ /* SO_TIMEOUT case. Val will be an integer with the new value */
+ /* Not writable on Linux */
+ case SOCKOPT_SO_TIMEOUT:
+#ifdef SO_TIMEOUT
+ mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+ optval = (*env)->CallIntMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_TIMEOUT (fd, optval, result);
+#else
+ result = TARGET_NATIVE_OK;
+#endif
+ break;
+
+ case SOCKOPT_SO_SNDBUF:
+ case SOCKOPT_SO_RCVBUF:
+ mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+
+ optval = (*env)->CallIntMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ if (option_id == SOCKOPT_SO_SNDBUF)
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_SNDBUF (fd, optval,
+ result);
+ else
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_RCDBUF (fd, optval,
+ result);
+ break;
+
+ /* TTL case. Val with be an Integer with the new time to live value */
+ case SOCKOPT_IP_TTL:
+ mid = (*env)->GetMethodID (env, cls, "intValue", "()I");
+ if (!mid)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+ optval = (*env)->CallIntMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_TTL (fd, optval, result);
+ break;
+
+ /* Multicast Interface case - val is InetAddress object */
+ case SOCKOPT_IP_MULTICAST_IF:
+ address = _javanet_get_netaddr (env, val);
+
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_MULTICAST_IF (fd, address,
+ result);
+ break;
+
+ case SOCKOPT_SO_REUSEADDR:
+ mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+ /* Should be a 0 or a 1 */
+ optval = (*env)->CallBooleanMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_REUSE_ADDRESS (fd, optval,
+ result);
+ break;
+
+ case SOCKOPT_SO_KEEPALIVE:
+ mid = (*env)->GetMethodID (env, cls, "booleanValue", "()Z");
+ if (mid == NULL)
+ {
+ JCL_ThrowException (env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()");
+ return;
+ }
+
+ /* Should be a 0 or a 1 */
+ optval = (*env)->CallBooleanMethod (env, val, mid);
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_KEEP_ALIVE (fd, optval, result);
+ break;
+
+ case SOCKOPT_SO_BINDADDR:
+ JCL_ThrowException (env, SOCKET_EXCEPTION, "This option cannot be set");
+ break;
+
+ default:
+ JCL_ThrowException (env, SOCKET_EXCEPTION, "Unrecognized option");
+ return;
+ }
+
+ /* Check to see if above operations succeeded */
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return;
+ }
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Retrieves the specified option values for a socket
+ */
+jobject
+_javanet_get_option (JNIEnv * env, jobject this, jint option_id)
+{
+#ifndef WITHOUT_NETWORK
+ int fd;
+ int flag, optval;
+ int address;
+ int result;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "Internal error: _javanet_get_option(): no native file descriptor");
+ return (0);
+ }
+
+ /* Process the option requested */
+ switch (option_id)
+ {
+ /* TCP_NODELAY case. Return a Boolean indicating on or off */
+ case SOCKOPT_TCP_NODELAY:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_TCP_NODELAY (fd, optval,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ if (optval)
+ return (_javanet_create_boolean (env, JNI_TRUE));
+ else
+ return (_javanet_create_boolean (env, JNI_FALSE));
+
+ break;
+
+ /* SO_LINGER case. If disabled, return a Boolean object that represents
+ false, else return an Integer that is the value of SO_LINGER */
+ case SOCKOPT_SO_LINGER:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_LINGER (fd, flag, optval,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ if (optval)
+ return (_javanet_create_integer (env, JNI_TRUE));
+ else
+ return (_javanet_create_boolean (env, JNI_FALSE));
+
+ break;
+
+ /* SO_TIMEOUT case. Return an Integer object with the timeout value */
+ case SOCKOPT_SO_TIMEOUT:
+#ifdef SO_TIMEOUT
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_TIMEOUT (fd, optval, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+ return (_javanet_create_integer (env, optval));
+#else
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "SO_TIMEOUT not supported on this platform");
+ return (0);
+#endif /* not SO_TIMEOUT */
+ break;
+
+ case SOCKOPT_SO_SNDBUF:
+ case SOCKOPT_SO_RCVBUF:
+ if (option_id == SOCKOPT_SO_SNDBUF)
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_SNDBUF (fd, optval,
+ result);
+ else
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_RCDBUF (fd, optval,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ return (_javanet_create_integer (env, optval));
+ break;
+
+ /* The TTL case. Return an Integer with the Time to Live value */
+ case SOCKOPT_IP_TTL:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_TTL (fd, optval, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ return (_javanet_create_integer (env, optval));
+ break;
+
+ /* Multicast interface case */
+ case SOCKOPT_IP_MULTICAST_IF:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_IP_MULTICAST_IF (fd, address,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ return (_javanet_create_inetaddress (env, address));
+ break;
+
+ case SOCKOPT_SO_BINDADDR:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_BIND_ADDRESS (fd, address,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ return (_javanet_create_inetaddress (env, address));
+ break;
+
+ case SOCKOPT_SO_REUSEADDR:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_REUSE_ADDRESS (fd, optval,
+ result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ if (optval)
+ return (_javanet_create_boolean (env, JNI_TRUE));
+ else
+ return (_javanet_create_boolean (env, JNI_FALSE));
+
+ break;
+
+ case SOCKOPT_SO_KEEPALIVE:
+ TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_KEEP_ALIVE (fd, optval, result);
+ if (result != TARGET_NATIVE_OK)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ TARGET_NATIVE_LAST_ERROR_STRING ());
+ return (0);
+ }
+
+ if (optval)
+ return (_javanet_create_boolean (env, JNI_TRUE));
+ else
+ return (_javanet_create_boolean (env, JNI_FALSE));
+
+ break;
+
+ default:
+ JCL_ThrowException (env, SOCKET_EXCEPTION, "No such option");
+ return (0);
+ }
+
+ return (0);
+#else /* not WITHOUT_NETWORK */
+#endif /* not WITHOUT_NETWORK */
+}
+
+void
+_javanet_shutdownInput (JNIEnv * env, jobject this)
+{
+ int fd;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor. */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "Internal error: _javanet_get_option(): no native file descriptor");
+ return;
+ }
+
+ /* Shutdown input stream of socket. */
+ if (shutdown (fd, SHUT_RD) == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "Can't shutdown input of socket");
+ return;
+ }
+}
+
+void
+_javanet_shutdownOutput (JNIEnv * env, jobject this)
+{
+ int fd;
+
+ assert (env != NULL);
+ assert ((*env) != NULL);
+
+ /* Get the real file descriptor. */
+ fd = _javanet_get_int_field (env, this, "native_fd");
+ if (fd == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "Internal error: _javanet_get_option(): no native file descriptor");
+ return;
+ }
+
+ /* Shutdown output stream of socket. */
+ if (shutdown (fd, SHUT_WR) == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "Can't shutdown output of socket");
+ return;
+ }
+}
+
+/* end of file */
diff --git a/libjava/classpath/native/jni/java-net/javanet.h b/libjava/classpath/native/jni/java-net/javanet.h
new file mode 100644
index 00000000000..7c77ea77f84
--- /dev/null
+++ b/libjava/classpath/native/jni/java-net/javanet.h
@@ -0,0 +1,109 @@
+/* javanet.h - Declarations for common functions for the java.net package
+ Copyright (C) 1998, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+#ifndef _JAVANET_LOADED
+#define _JAVANET_LOADED
+
+#include <jni.h>
+
+/*************************************************************************/
+
+/*
+ * Defined constants
+ */
+
+/* Exception Classes */
+#define BIND_EXCEPTION "java/net/BindException"
+#define IO_EXCEPTION "java/io/IOException"
+#define SOCKET_EXCEPTION "java/net/SocketException"
+#define UNKNOWN_HOST_EXCEPTION "java/net/UnknownHostException"
+
+/* Socket Option Identifiers - Don't change or binary compatibility with
+ the JDK will be broken! These also need to
+ be kept compatible with java.net.SocketOptions */
+#define SOCKOPT_TCP_NODELAY 1
+#define SOCKOPT_SO_BINDADDR 15
+#define SOCKOPT_SO_LINGER 128
+#define SOCKOPT_SO_TIMEOUT 4102
+#define SOCKOPT_SO_SNDBUF 4097
+#define SOCKOPT_SO_RCVBUF 4098
+#define SOCKOPT_SO_REUSEADDR 4
+#define SOCKOPT_IP_MULTICAST_IF 16
+#define SOCKOPT_SO_KEEPALIVE 8
+
+/* Internal option identifiers. Not needed for JDK compatibility */
+#define SOCKOPT_IP_TTL 7777
+
+/*************************************************************************/
+
+/*
+ * Macros
+ */
+
+/* Simple debug macro */
+#ifdef DEBUG
+#define DBG(x) fprintf(stderr, (x));
+#else
+#define DBG(x)
+#endif
+
+/*************************************************************************/
+
+/*
+ * Function Prototypes
+ */
+
+extern int _javanet_get_int_field(JNIEnv *, jobject, const char *);
+extern int _javanet_get_netaddr(JNIEnv *, jobject);
+extern void _javanet_create(JNIEnv *, jobject, jboolean);
+extern void _javanet_close(JNIEnv *, jobject, int);
+extern void _javanet_connect(JNIEnv *, jobject, jobject, jint);
+extern void _javanet_bind(JNIEnv *, jobject, jobject, jint, int);
+extern void _javanet_listen(JNIEnv *, jobject, jint);
+extern void _javanet_accept(JNIEnv *, jobject, jobject);
+extern int _javanet_recvfrom(JNIEnv *, jobject, jarray, int, int, int *, int *);
+extern void _javanet_sendto(JNIEnv *, jobject, jarray, int, int, int, int);
+extern jobject _javanet_get_option(JNIEnv *, jobject, jint);
+extern void _javanet_set_option(JNIEnv *, jobject, jint, jobject);
+extern void _javanet_shutdownInput (JNIEnv *, jobject);
+extern void _javanet_shutdownOutput (JNIEnv *, jobject);
+
+/*************************************************************************/
+
+#endif /* not _JAVANET_H_LOADED */
+
OpenPOWER on IntegriCloud