summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/native/jni/java-net
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-09 19:58:05 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2007-01-09 19:58:05 +0000
commit65bf3316cf384588453604be6b4f0ed3751a8b0f (patch)
tree996a5f57d4a68c53473382e45cb22f574cb3e4db /libjava/classpath/native/jni/java-net
parent8fc56618a84446beccd45b80381cdfe0e94050df (diff)
downloadppe42-gcc-65bf3316cf384588453604be6b4f0ed3751a8b0f.tar.gz
ppe42-gcc-65bf3316cf384588453604be6b4f0ed3751a8b0f.zip
Merged gcj-eclipse branch to trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120621 138bc75d-0d04-0410-961f-82ee72b054a4
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.am5
-rw-r--r--libjava/classpath/native/jni/java-net/Makefile.in24
-rw-r--r--libjava/classpath/native/jni/java-net/gnu_java_net_VMPlainDatagramSocketImpl.c399
-rw-r--r--libjava/classpath/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c1003
-rw-r--r--libjava/classpath/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c2
-rw-r--r--libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c201
-rw-r--r--libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c206
-rw-r--r--libjava/classpath/native/jni/java-net/javanet.c551
-rw-r--r--libjava/classpath/native/jni/java-net/javanet.h9
-rw-r--r--libjava/classpath/native/jni/java-net/local.c2
11 files changed, 1473 insertions, 937 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
index 26bb64f73bf..1278b946c63 100644
--- a/libjava/classpath/native/jni/java-net/Makefile.am
+++ b/libjava/classpath/native/jni/java-net/Makefile.am
@@ -13,11 +13,12 @@ libjavanet_la_SOURCES = javanet.c \
java_net_VMInetAddress.c \
java_net_VMNetworkInterface.c \
java_net_VMURLConnection.c \
- gnu_java_net_VMPlainDatagramSocketImpl.c \
gnu_java_net_VMPlainSocketImpl.c \
$(local_sources)
-libjavanet_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo $(LIBMAGIC)
+libjavanet_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo \
+ $(top_builddir)/native/jni/native-lib/libclasspathnative.la \
+ $(LIBMAGIC)
AM_LDFLAGS = @CLASSPATH_MODULE@
AM_CPPFLAGS = @CLASSPATH_INCLUDES@
diff --git a/libjava/classpath/native/jni/java-net/Makefile.in b/libjava/classpath/native/jni/java-net/Makefile.in
index c427f8cd5bb..ec8f6a858d7 100644
--- a/libjava/classpath/native/jni/java-net/Makefile.in
+++ b/libjava/classpath/native/jni/java-net/Makefile.in
@@ -42,12 +42,14 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../../config/depstand.m4 \
$(top_srcdir)/../../config/lead-dot.m4 \
+ $(top_srcdir)/../../config/no-executables.m4 \
$(top_srcdir)/../../libtool.m4 $(top_srcdir)/m4/acattribute.m4 \
$(top_srcdir)/m4/accross.m4 $(top_srcdir)/m4/acinclude.m4 \
$(top_srcdir)/m4/ax_create_stdint_h.m4 \
- $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \
- $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
- $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gcc_attribute.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/pkg.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@@ -65,19 +67,17 @@ LTLIBRARIES = $(nativeexeclib_LTLIBRARIES)
am__DEPENDENCIES_1 =
libjavanet_la_DEPENDENCIES = \
$(top_builddir)/native/jni/classpath/jcl.lo \
+ $(top_builddir)/native/jni/native-lib/libclasspathnative.la \
$(am__DEPENDENCIES_1)
am__libjavanet_la_SOURCES_DIST = javanet.c javanet.h \
java_net_VMInetAddress.c java_net_VMNetworkInterface.c \
- java_net_VMURLConnection.c \
- gnu_java_net_VMPlainDatagramSocketImpl.c \
- gnu_java_net_VMPlainSocketImpl.c \
+ java_net_VMURLConnection.c gnu_java_net_VMPlainSocketImpl.c \
gnu_java_net_local_LocalSocketImpl.c local.c local.h
@ENABLE_LOCAL_SOCKETS_FALSE@am__objects_1 = gnu_java_net_local_LocalSocketImpl.lo
@ENABLE_LOCAL_SOCKETS_TRUE@am__objects_1 = gnu_java_net_local_LocalSocketImpl.lo \
@ENABLE_LOCAL_SOCKETS_TRUE@ local.lo
am_libjavanet_la_OBJECTS = javanet.lo java_net_VMInetAddress.lo \
java_net_VMNetworkInterface.lo java_net_VMURLConnection.lo \
- gnu_java_net_VMPlainDatagramSocketImpl.lo \
gnu_java_net_VMPlainSocketImpl.lo $(am__objects_1)
libjavanet_la_OBJECTS = $(am_libjavanet_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include
@@ -198,6 +198,8 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION = @JAVA_LANG_SYSTEM_EXPLICIT_INITIALIZATION@
+JAVA_MAINTAINER_MODE_FALSE = @JAVA_MAINTAINER_MODE_FALSE@
+JAVA_MAINTAINER_MODE_TRUE = @JAVA_MAINTAINER_MODE_TRUE@
JAY = @JAY@
JAY_SKELETON = @JAY_SKELETON@
JIKES = @JIKES@
@@ -319,7 +321,6 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
-toolexeclibdir = @toolexeclibdir@
vm_classes = @vm_classes@
nativeexeclib_LTLIBRARIES = libjavanet.la
@ENABLE_LOCAL_SOCKETS_FALSE@local_sources = gnu_java_net_local_LocalSocketImpl.c
@@ -332,11 +333,13 @@ libjavanet_la_SOURCES = javanet.c \
java_net_VMInetAddress.c \
java_net_VMNetworkInterface.c \
java_net_VMURLConnection.c \
- gnu_java_net_VMPlainDatagramSocketImpl.c \
gnu_java_net_VMPlainSocketImpl.c \
$(local_sources)
-libjavanet_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo $(LIBMAGIC)
+libjavanet_la_LIBADD = $(top_builddir)/native/jni/classpath/jcl.lo \
+ $(top_builddir)/native/jni/native-lib/libclasspathnative.la \
+ $(LIBMAGIC)
+
AM_LDFLAGS = @CLASSPATH_MODULE@
AM_CPPFLAGS = @CLASSPATH_INCLUDES@
AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@
@@ -409,7 +412,6 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_java_net_VMPlainDatagramSocketImpl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_java_net_VMPlainSocketImpl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnu_java_net_local_LocalSocketImpl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/java_net_VMInetAddress.Plo@am__quote@
diff --git a/libjava/classpath/native/jni/java-net/gnu_java_net_VMPlainDatagramSocketImpl.c b/libjava/classpath/native/jni/java-net/gnu_java_net_VMPlainDatagramSocketImpl.c
deleted file mode 100644
index 1b3cb97e0d0..00000000000
--- a/libjava/classpath/native/jni/java-net/gnu_java_net_VMPlainDatagramSocketImpl.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/* VMPlainDatagramSocketImpl.c - Native methods for PlainDatagramSocketImpl
- Copyright (C) 2005, 2006 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 <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_VMPlainDatagramSocketImpl.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_VMPlainDatagramSocketImpl_create(JNIEnv *env,
- jclass klass __attribute__ ((__unused__))
- , jobject obj)
-{
-
-#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_VMPlainDatagramSocketImpl_close(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj)
-{
-
-#ifndef WITHOUT_NETWORK
- _javanet_close(env, obj, 0);
-#else /* not WITHOUT_NETWORK */
-#endif /* not WITHOUT_NETWORK */
-}
-
-/*************************************************************************/
-
-/*
- * Connects to the specified destination.
- */
-JNIEXPORT void JNICALL
-Java_gnu_java_net_VMPlainDatagramSocketImpl_connect(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj,
- jobject addr, jint port)
-{
-#ifndef WITHOUT_NETWORK
-
- _javanet_connect(env, obj, addr, port, 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_VMPlainDatagramSocketImpl_bind(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj,
- jint port, jobject addr)
-{
-
-#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_VMPlainDatagramSocketImpl_setOption(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj,
- jint option_id,
- jobject val)
-{
-
-#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_VMPlainDatagramSocketImpl_getOption(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj,
- jint option_id)
-{
-
-#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_VMPlainDatagramSocketImpl_nativeReceive(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj,
- jbyteArray arr,
- jint offset,
- jint length,
- jbyteArray receivedFromAddress,
- jintArray receivedFromPort,
- jintArray receivedLength)
-{
-#ifndef WITHOUT_NETWORK
- int addr, *port, *bytes_read;
- char *addressBytes;
-
- addr = 0;
-
- port = (int*)(*env)->GetIntArrayElements(env, receivedFromPort, NULL);
- if (port == NULL)
- {
- JCL_ThrowException(env, IO_EXCEPTION, "Internal error: could not access receivedFromPort array");
- return;
- }
-
- bytes_read = (int*)(*env)->GetIntArrayElements(env, receivedLength, NULL);
- if (bytes_read == NULL)
- {
- (*env)->ReleaseIntArrayElements(env, receivedFromPort, (jint*)port, 0);
- JCL_ThrowException(env, IO_EXCEPTION, "Internal error: could not access receivedLength array");
- return;
- }
-
- /* Receive the packet */
- /* should we try some sort of validation on the length? */
- (*bytes_read) = _javanet_recvfrom(env, obj, arr, offset, length, &addr, port);
-
- /* Special case the strange situation where the receiver didn't want any
- bytes. */
- if (length == 0 && (*bytes_read) == -1)
- *bytes_read = 0;
-
- if ((*bytes_read) == -1)
- {
- (*env)->ReleaseIntArrayElements(env, receivedFromPort, (jint*)port, 0);
- (*env)->ReleaseIntArrayElements(env, receivedLength, (jint*)bytes_read, 0);
- JCL_ThrowException(env, IO_EXCEPTION, "Internal error: receive");
- return;
- }
-
- (*env)->ReleaseIntArrayElements(env, receivedFromPort, (jint*)port, 0);
- (*env)->ReleaseIntArrayElements(env, receivedLength, (jint*)bytes_read, 0);
-
- if ((*env)->ExceptionOccurred(env))
- {
- return;
- }
-
- DBG("PlainDatagramSocketImpl.receive(): Received packet\n");
-
-
- /* Store the address */
- addressBytes = (char*)(*env)->GetPrimitiveArrayCritical(env, receivedFromAddress, NULL);
- TARGET_NATIVE_NETWORK_INT_TO_IPADDRESS_BYTES(addr,
- addressBytes[0],
- addressBytes[1],
- addressBytes[2],
- addressBytes[3]
- );
- (*env)->ReleasePrimitiveArrayCritical(env, receivedFromAddress, addressBytes, 0);
-
-#else /* not WITHOUT_NETWORK */
-#endif /* not WITHOUT_NETWORK */
-}
-
-/*************************************************************************/
-
-/*
- * Writes a buffer to the remote host
- */
-JNIEXPORT void JNICALL
-Java_gnu_java_net_VMPlainDatagramSocketImpl_nativeSendTo(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj,
- jobject addr,
- jint port,
- jarray buf,
- jint offset,
- jint len)
-{
-#ifndef WITHOUT_NETWORK
- jint netAddress;
-
- /* check if address given, tr 7.3.2005 */
- if (addr != NULL)
- {
- netAddress = _javanet_get_netaddr(env, addr);
- if ((*env)->ExceptionOccurred(env))
- {
- return;
- }
- }
- else
- {
- netAddress = 0;
- }
-
- 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_VMPlainDatagramSocketImpl_join(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj,
- jobject addr)
-{
-#ifndef WITHOUT_NETWORK
- jint netAddress;
- int fd;
- int result;
-
- /* check if address given, tr 7.3.2005 */
- if (addr != NULL)
- {
- netAddress = _javanet_get_netaddr(env, addr);
- if ((*env)->ExceptionOccurred(env))
- {
- JCL_ThrowException(env, IO_EXCEPTION, "Internal error");
- return;
- }
- }
- else
- {
- netAddress = 0;
- }
-
- fd = _javanet_get_int_field(env, obj, "native_fd");
- if ((*env)->ExceptionOccurred(env))
- {
- JCL_ThrowException(env, IO_EXCEPTION, "Internal error");
- 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_VMPlainDatagramSocketImpl_leave(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj,
- jobject addr)
-{
-#ifndef WITHOUT_NETWORK
- jint netAddress;
- int fd;
- int result;
-
- /* check if address given, tr 7.3.2005 */
- if (addr != NULL)
- {
- netAddress = _javanet_get_netaddr(env, addr);
- if ((*env)->ExceptionOccurred(env))
- {
- JCL_ThrowException(env, IO_EXCEPTION, "Internal error");
- return;
- }
- }
- else
- {
- netAddress = 0;
- }
-
- fd = _javanet_get_int_field(env, obj, "native_fd");
- if ((*env)->ExceptionOccurred(env))
- { JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); 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_VMPlainSocketImpl.c b/libjava/classpath/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c
index 3d48b9195c4..cdfbe739789 100644
--- a/libjava/classpath/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c
+++ b/libjava/classpath/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c
@@ -35,269 +35,930 @@ 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>
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <config-int.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#endif
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <net/if.h>
+#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <unistd.h>
#include <jni.h>
#include <jcl.h>
+#include "cpnative.h"
+#include "cpnet.h"
+#include "cpio.h"
#include "javanet.h"
-#include "target_native.h"
-#ifndef WITHOUT_NETWORK
- #include "target_native_file.h" /* Get FIONREAD on Solaris. */
- #include "target_native_network.h"
-#endif /* WITHOUT_NETWORK */
-
#include "gnu_java_net_VMPlainSocketImpl.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.
- */
-
-/*************************************************************************/
+#define THROW_NO_NETWORK(env) JCL_ThrowException (env, "java/lang/InternalError", "this platform not configured for network support")
/*
- * Creates a new stream or datagram socket
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: bind
+ * Signature: (I[BI)V
*/
JNIEXPORT void JNICALL
-Java_gnu_java_net_VMPlainSocketImpl_create(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj)
+Java_gnu_java_net_VMPlainSocketImpl_bind (JNIEnv *env,
+ jclass clazz __attribute__((unused)),
+ jint fd, jbyteArray addr, jint port)
{
-#ifndef WITHOUT_NETWORK
- _javanet_create(env, obj, JNI_TRUE);
-#else /* not WITHOUT_NETWORK */
-#endif /* not WITHOUT_NETWORK */
+ struct sockaddr_in sockaddr;
+ jbyte *elems = NULL;
+ int ret;
+
+ if (addr != NULL)
+ elems = (*env)->GetByteArrayElements (env, addr, NULL);
+
+ memset(&sockaddr, 0, sizeof (struct sockaddr_in));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons (port);
+ /* addr is already in network byte order. */
+ if (elems != NULL)
+ sockaddr.sin_addr.s_addr = *((uint32_t *) elems);
+ else
+ sockaddr.sin_addr.s_addr = INADDR_ANY;
+
+ /* bind(2) from BSD says bind will never return EINTR */
+ /* bind is not a blocking system call */
+ ret = bind (fd, (struct sockaddr *) &sockaddr, sizeof (struct sockaddr_in));
+
+ if (elems != NULL)
+ (*env)->ReleaseByteArrayElements (env, addr, elems, JNI_ABORT);
+
+ if (-1 == ret)
+ JCL_ThrowException (env, BIND_EXCEPTION, strerror (errno));
+
+ cpio_closeOnExec(ret);
}
-/*************************************************************************/
/*
- * Close the socket. Any underlying streams will be closed by this
- * action as well.
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: bind6
+ * Signature: (I[BI)V
*/
JNIEXPORT void JNICALL
-Java_gnu_java_net_VMPlainSocketImpl_close(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj)
+Java_gnu_java_net_VMPlainSocketImpl_bind6 (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jbyteArray addr, jint port)
{
-#ifndef WITHOUT_NETWORK
- _javanet_close(env, obj, 1);
-#else /* not WITHOUT_NETWORK */
-#endif /* not WITHOUT_NETWORK */
+ /* FIXME! Add check if we have IPv6! */
+ struct sockaddr_in6 sockaddr;
+ jbyte *elems;
+ int ret;
+
+ elems = (*env)->GetByteArrayElements (env, addr, NULL);
+
+ memset (&sockaddr, 0, sizeof (struct sockaddr_in6));
+ sockaddr.sin6_family = AF_INET6;
+ sockaddr.sin6_port = htons (port);
+ memcpy (&sockaddr.sin6_addr.s6_addr, elems, 16);
+
+ /* bind(2) from BSD says bind will never return EINTR */
+ /* bind is not a blocking system call */
+ ret = bind (fd, (struct sockaddr *) &sockaddr,
+ sizeof (struct sockaddr_in6));
+
+ (*env)->ReleaseByteArrayElements (env, addr, elems, JNI_ABORT);
+
+ if (-1 == ret)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
}
-/*************************************************************************/
/*
- * Connects to the specified destination.
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: listen
+ * Signature: (II)V
*/
JNIEXPORT void JNICALL
-Java_gnu_java_net_VMPlainSocketImpl_connect(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj,
- jobject addr, jint port)
+Java_gnu_java_net_VMPlainSocketImpl_listen (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jint backlog)
{
-#ifndef WITHOUT_NETWORK
- _javanet_connect(env, obj, addr, port, 1);
-#else /* not WITHOUT_NETWORK */
-#endif /* not WITHOUT_NETWORK */
+ int ret;
+
+ /* listen(2) says that this call will never return EINTR */
+ /* listen is not a blocking system call */
+ if ((ret = listen (fd, backlog)) == -1)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
}
-/*************************************************************************/
-/*
- * 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.
+/* These constants are also defined in java/net/SocketOptions.java.
+ * Except for CPNET_IP_TTL which is defined in
+ * vm/reference/gnu/java/net/VMPlainSocketImpl.java .
*/
-JNIEXPORT void JNICALL
-Java_gnu_java_net_VMPlainSocketImpl_bind(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj, jobject addr,
- jint port)
-{
-#ifndef WITHOUT_NETWORK
- _javanet_bind(env, obj, addr, port, 1);
-#else /* not WITHOUT_NETWORK */
-#endif /* not WITHOUT_NETWORK */
-}
+enum java_sockopt {
+ CPNET_SO_KEEPALIVE = 0x8,
+ CPNET_SO_LINGER = 0x80,
+ CPNET_SO_TIMEOUT = 0x1006,
+ CPNET_SO_BINDADDR = 0x0F,
+ CPNET_SO_SNDBUF = 0x1001,
+ CPNET_SO_RCVBUF = 0x1002,
+ CPNET_SO_REUSEADDR = 0x04,
+ CPNET_SO_BROADCAST = 0x20,
+ CPNET_SO_OOBINLINE = 0x1003,
+ CPNET_TCP_NODELAY = 0x01,
+ CPNET_IP_MULTICAST_IF = 0x10,
+ CPNET_IP_MULTICAST_IF2 = 0x1F,
+ CPNET_IP_MULTICAST_LOOP = 0x12,
+ CPNET_IP_TOS = 0x03,
+ CPNET_IP_TTL = 0x1E61
+};
-/*************************************************************************/
/*
- * Starts listening on a socket with the specified number of pending
- * connections allowed.
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: setOption
+ * Signature: (III)V
*/
JNIEXPORT void JNICALL
-Java_gnu_java_net_VMPlainSocketImpl_listen(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj, jint queuelen)
+Java_gnu_java_net_VMPlainSocketImpl_setOption (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jint option, jint value)
{
-#ifndef WITHOUT_NETWORK
- _javanet_listen(env, obj, queuelen);
-#else /* not WITHOUT_NETWORK */
-#endif /* not WITHOUT_NETWORK */
-}
+ enum java_sockopt joption = (enum java_sockopt) option;
+ int optname = -1;
+ int level = SOL_SOCKET;
+ const int _value = value;
+ struct linger _linger;
+ struct timeval _timeo;
+ void *optval = (void *) &_value;
+ socklen_t optlen = sizeof (int);
+
+ switch (joption)
+ {
+ case CPNET_IP_MULTICAST_LOOP:
+ level = IPPROTO_IP;
+ optname = IP_MULTICAST_LOOP;
+ break;
+
+ case CPNET_SO_KEEPALIVE:
+ optname = SO_KEEPALIVE;
+ break;
+
+ case CPNET_SO_LINGER:
+ optname = SO_LINGER;
+ if (_value == -1)
+ _linger.l_onoff = 0;
+ else
+ _linger.l_onoff = 1;
+ _linger.l_linger = _value;
+ optval = &_linger;
+ optlen = sizeof (struct linger);
+ break;
+
+ case CPNET_SO_TIMEOUT:
+ optname = SO_RCVTIMEO;
+ _timeo.tv_sec = value / 1000;
+ _timeo.tv_usec = (value % 1000) * 1000;
+ optval = &_timeo;
+ optlen = sizeof (struct timeval);
+ break;
+
+ case CPNET_SO_SNDBUF:
+ optname = SO_SNDBUF;
+ break;
+
+ case CPNET_SO_RCVBUF:
+ optname = SO_RCVBUF;
+ break;
+
+ case CPNET_SO_REUSEADDR:
+ optname = SO_REUSEADDR;
+ break;
+
+ case CPNET_SO_BROADCAST:
+ optname = SO_BROADCAST;
+ break;
+
+ case CPNET_SO_OOBINLINE:
+ optname = SO_OOBINLINE;
+ break;
+
+ case CPNET_TCP_NODELAY:
+ level = IPPROTO_TCP;
+ optname = TCP_NODELAY;
+ break;
+
+ case CPNET_IP_TOS:
+ level = IPPROTO_IP;
+ optname = IP_TOS;
+ break;
+
+ case CPNET_IP_TTL:
+ level = IPPROTO_IP;
+ optname = IP_TTL;
+ break;
+
+ case CPNET_SO_BINDADDR:
+ case CPNET_IP_MULTICAST_IF:
+ case CPNET_IP_MULTICAST_IF2:
+ JCL_ThrowException (env, IO_EXCEPTION, "argument not a boolean or integer option");
+ return;
+ }
-/*************************************************************************/
+ if (setsockopt (fd, level, optname, (const void *) optval, optlen) == -1)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+}
/*
- * Accepts a new connection and assigns it to the passed in SocketImpl
- * object. Note that we assume this is a PlainSocketImpl just like us.
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: getOption
+ * Signature: (II)I
*/
-JNIEXPORT void JNICALL
-Java_gnu_java_net_VMPlainSocketImpl_accept(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj, jobject impl)
+JNIEXPORT jint JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_getOption (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jint option)
{
-#ifndef WITHOUT_NETWORK
- _javanet_accept(env, obj, impl);
-#else /* not WITHOUT_NETWORK */
-#endif /* not WITHOUT_NETWORK */
-}
+ enum java_sockopt joption = (enum java_sockopt) option;
+ int optname = -1;
+ int level = SOL_SOCKET;
+ int value;
+ struct linger linger;
+ struct timeval timeo;
+ void *optval = &value;
+ socklen_t optlen = sizeof (int);
+
+ switch (joption)
+ {
+ case CPNET_IP_MULTICAST_LOOP:
+ level = IPPROTO_IP;
+ optname = IP_MULTICAST_LOOP;
+ break;
+
+ case CPNET_SO_KEEPALIVE:
+ optname = SO_KEEPALIVE;
+ break;
+
+ case CPNET_SO_LINGER:
+ optname = SO_LINGER;
+ optval = &linger;
+ optlen = sizeof (struct linger);
+ break;
+
+ case CPNET_SO_TIMEOUT:
+ optname = SO_RCVTIMEO;
+ optval = &timeo;
+ optlen = sizeof (struct timeval);
+ break;
+
+ case CPNET_SO_SNDBUF:
+ optname = SO_SNDBUF;
+ break;
+
+ case CPNET_SO_RCVBUF:
+ optname = SO_RCVBUF;
+ break;
+
+ case CPNET_SO_REUSEADDR:
+ optname = SO_REUSEADDR;
+ break;
+
+ case CPNET_SO_BROADCAST:
+ optname = SO_BROADCAST;
+ break;
+
+ case CPNET_SO_OOBINLINE:
+ optname = SO_OOBINLINE;
+ break;
+
+ case CPNET_TCP_NODELAY:
+ level = IPPROTO_TCP;
+ optname = TCP_NODELAY;
+ break;
+
+ case CPNET_IP_TOS:
+ level = IPPROTO_IP;
+ optname = IP_TOS;
+ break;
+
+ case CPNET_IP_TTL:
+ level = IPPROTO_IP;
+ optname = IP_TTL;
+ break;
+
+ case CPNET_SO_BINDADDR:
+ case CPNET_IP_MULTICAST_IF:
+ case CPNET_IP_MULTICAST_IF2:
+ JCL_ThrowException (env, IO_EXCEPTION, "argument not a boolean or integer option");
+ return -1;
+ }
-/*************************************************************************/
+ if (getsockopt (fd, level, optname, optval, &optlen) == -1)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
-JNIEXPORT jint JNICALL
-Java_gnu_java_net_VMPlainSocketImpl_available(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj)
+ /* Returns the linger value if it is enabled or -1 in case
+ * it is disabled. This is how the Java API expects it.
+ */
+ if (joption == CPNET_SO_LINGER)
+ return (linger.l_onoff) ? linger.l_linger : -1;
+ if (joption == CPNET_SO_TIMEOUT)
+ return (timeo.tv_sec * 1000) + (timeo.tv_usec / 1000);
+
+ return value;
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_setMulticastInterface (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd,
+ jint optionId __attribute__((unused)),
+ jobject addr)
{
-#ifndef WITHOUT_NETWORK
- jclass cls;
- jfieldID fid;
- int fd;
- int bytesAvailable;
- int result;
+ int result;
+ cpnet_address *cpaddr = _javanet_get_ip_netaddr (env, addr);
+
+ if ((*env)->ExceptionOccurred (env))
+ return;
+
+ result = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
+ (struct sockaddr *) cpaddr->data, cpaddr->len);
+
+ cpnet_freeAddress (env, cpaddr);
- cls = (*env)->GetObjectClass(env, obj);
- if (cls == 0)
+ if (result == -1)
+ JCL_ThrowException (env, SOCKET_EXCEPTION, cpnative_getErrorString (errno));
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_setMulticastInterface6 (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd,
+ jint optionId __attribute__((unused)),
+ jstring ifname)
+{
+#ifdef HAVE_SETSOCKOPT
+#ifdef HAVE_INET6
+ int result;
+ const char *str_ifname = JCL_jstring_to_cstring (env, ifname);
+ u_int if_index;
+
+ if ((*env)->ExceptionOccurred (env))
{
- JCL_ThrowException(env, IO_EXCEPTION, "internal error");
- return 0;
+ JCL_free_cstring(env, ifname, str_ifname);
+ return;
}
-
- fid = (*env)->GetFieldID(env, cls, "native_fd", "I");
- if (fid == 0)
+
+ if_index = if_nametoindex(str_ifname);
+ if (!if_index)
{
- JCL_ThrowException(env, IO_EXCEPTION, "internal error");
- return 0;
+ JCL_free_cstring(env, ifname, str_ifname);
+ JCL_ThrowException (env, SOCKET_EXCEPTION, "interface does not exist");
+ return;
}
- fd = (*env)->GetIntField(env, obj, fid);
+ result = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
+ (u_int *) &if_index, sizeof(if_index));
+
+ JCL_free_cstring(env, ifname, str_ifname);
- TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_AVAILABLE(fd,bytesAvailable,result);
- if (result != TARGET_NATIVE_OK)
+ if (result == -1)
+ JCL_ThrowException (env, SOCKET_EXCEPTION, cpnative_getErrorString (errno));
+#else
+ (void) fd;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "IPv6 support not available");
+#endif /* HAVE_INET6 */
+#else
+ (void) fd;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "socket options not supported");
+#endif /* HAVE_SETSOCKOPT */
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_getMulticastInterface (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd,
+ jint optionId __attribute__((unused)))
+{
+ jobject obj;
+ cpnet_address *cpaddr;
+ int result = cpnet_getMulticastIF (env, fd, &cpaddr);
+
+ if (result != CPNATIVE_OK)
{
- JCL_ThrowException(env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING());
- return 0;
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ cpnative_getErrorString (result));
+ return (0);
}
- return bytesAvailable;
-#else /* not WITHOUT_NETWORK */
- return 0;
-#endif /* not WITHOUT_NETWORK */
+ obj = _javanet_create_inetaddress (env, cpaddr);
+ cpnet_freeAddress (env, cpaddr);
+
+ return obj;
}
-/*************************************************************************/
/*
- * This method sets the specified option for a socket
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: shutdownInput
+ * Signature: (I)V
*/
JNIEXPORT void JNICALL
-Java_gnu_java_net_VMPlainSocketImpl_setOption(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj,
- jint option_id, jobject val)
+Java_gnu_java_net_VMPlainSocketImpl_shutdownInput (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd)
{
-#ifndef WITHOUT_NETWORK
- _javanet_set_option(env, obj, option_id, val);
-#else /* not WITHOUT_NETWORK */
-#endif /* not WITHOUT_NETWORK */
+ if (shutdown (fd, SHUT_RD) == -1)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
+}
+
+/*
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: shutdownOutput
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_shutdownOutput (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd)
+{
+ if (shutdown (fd, SHUT_WR) == -1)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
}
-/*************************************************************************/
/*
- * This method gets the specified option for a socket
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: sendUrgentData
+ * Signature: (II)V
*/
-JNIEXPORT jobject JNICALL
-Java_gnu_java_net_VMPlainSocketImpl_getOption(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj,
- jint option_id)
+JNIEXPORT void JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_sendUrgentData (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jint data)
{
-#ifndef WITHOUT_NETWORK
- return(_javanet_get_option(env, obj, option_id));
-#else /* not WITHOUT_NETWORK */
- return NULL;
-#endif /* not WITHOUT_NETWORK */
+ const char x = (char) data;
+
+ if (send (fd, &x, 1, MSG_OOB) == -1)
+ JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
}
-/*************************************************************************/
/*
- * Reads a buffer from a remote host
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: join
+ * Signature: (I[B)V
*/
-JNIEXPORT jint JNICALL
-Java_gnu_java_net_VMPlainSocketImpl_read(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj, jarray buf,
- jint offset, jint len)
+JNIEXPORT void JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_join (JNIEnv *env,
+ jclass clazz __attribute__((unused)),
+ jint fd, jbyteArray addr)
{
-#ifndef WITHOUT_NETWORK
- return(_javanet_recvfrom(env, obj, buf, offset, len, 0, 0));
-#else /* not WITHOUT_NETWORK */
- return 0;
-#endif /* not WITHOUT_NETWORK */
+#ifdef HAVE_SETSOCKOPT
+ struct ip_mreq maddr;
+ jbyte *addr_elems;
+
+ addr_elems = (*env)->GetByteArrayElements (env, addr, NULL);
+ if (addr_elems == NULL)
+ return;
+
+ maddr.imr_multiaddr.s_addr = * ((uint32_t *) addr_elems);
+ maddr.imr_interface.s_addr = INADDR_ANY;
+
+ (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT);
+
+ if (-1 == setsockopt (fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ &maddr, sizeof (struct ip_mreq)))
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+#else
+ (void) fd;
+ (void) addr;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "socket options not supported");
+#endif /* HAVE_SETSOCKOPT */
}
-/*************************************************************************/
/*
- * Writes a buffer to the remote host
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: join6
+ * Signature: (I[B)V
*/
JNIEXPORT void JNICALL
-Java_gnu_java_net_VMPlainSocketImpl_write(JNIEnv *env,
- jclass klass __attribute__ ((__unused__)),
- jobject obj, jarray buf,
- jint offset, jint len)
+Java_gnu_java_net_VMPlainSocketImpl_join6 (JNIEnv *env,
+ jclass clazz __attribute__((unused)),
+ jint fd, jbyteArray addr)
{
-#ifndef WITHOUT_NETWORK
- _javanet_sendto(env, obj, buf, offset, len, 0, 0);
-#else /* not WITHOUT_NETWORK */
-#endif /* not WITHOUT_NETWORK */
+#ifdef HAVE_SETSOCKOPT
+#ifdef HAVE_INET6
+ struct ipv6_mreq maddr;
+ jbyte *addr_elems;
+
+ addr_elems = (*env)->GetByteArrayElements (env, addr, NULL);
+ if (addr_elems == NULL)
+ return;
+
+ memcpy (&(maddr.ipv6mr_multiaddr.s6_addr), addr_elems, 16);
+ maddr.ipv6mr_interface = 0;
+
+ (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT);
+
+ if (-1 == setsockopt (fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
+ &maddr, sizeof (struct ipv6_mreq)))
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+#else
+ (void) fd;
+ (void) addr;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "IPv6 support not available");
+#endif /* HAVE_INET6 */
+#else
+ (void) fd;
+ (void) addr;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "socket options not supported");
+#endif /* HAVE_SETSOCKOPT */
}
+/*
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: leave
+ * Signature: (I[B)V
+ */
JNIEXPORT void JNICALL
-Java_gnu_java_net_VMPlainSocketImpl_shutdownInput (JNIEnv * env,
- jclass klass __attribute__ ((__unused__)),
- jobject this)
+Java_gnu_java_net_VMPlainSocketImpl_leave (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jbyteArray addr)
{
-#ifndef WITHOUT_NETWORK
- _javanet_shutdownInput (env, this);
-#else /* not WITHOUT_NETWORK */
-#endif /* not WITHOUT_NETWORK */
+#ifdef HAVE_SETSOCKOPT
+ struct ip_mreq maddr;
+ jbyte *addr_elems;
+
+ addr_elems = (*env)->GetByteArrayElements (env, addr, NULL);
+ if (addr_elems == NULL)
+ return;
+
+ maddr.imr_multiaddr.s_addr = * ((uint32_t *) addr_elems);
+ maddr.imr_interface.s_addr = INADDR_ANY;
+
+ (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT);
+
+ if (-1 == setsockopt (fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+ &maddr, sizeof (struct ip_mreq)))
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+#else
+ (void) fd;
+ (void) addr;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "socket options not supported");
+#endif /* HAVE_SETSOCKOPT */
}
+/*
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: leave6
+ * Signature: (I[B)V
+ */
JNIEXPORT void JNICALL
-Java_gnu_java_net_VMPlainSocketImpl_shutdownOutput (JNIEnv * env,
- jclass klass __attribute__ ((__unused__)),
- jobject this)
+Java_gnu_java_net_VMPlainSocketImpl_leave6 (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jbyteArray addr)
{
-#ifndef WITHOUT_NETWORK
- _javanet_shutdownOutput (env, this);
-#else /* not WITHOUT_NETWORK */
-#endif /* not WITHOUT_NETWORK */
+#ifdef HAVE_SETSOCKOPT
+#ifdef HAVE_INET6
+ struct ipv6_mreq maddr;
+ jbyte *addr_elems;
+
+ addr_elems = (*env)->GetByteArrayElements (env, addr, NULL);
+ if (addr_elems == NULL)
+ return;
+
+ memcpy (&(maddr.ipv6mr_multiaddr.s6_addr), addr_elems, 16);
+ maddr.ipv6mr_interface = 0;
+
+ (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT);
+
+ if (-1 == setsockopt (fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
+ &maddr, sizeof (struct ipv6_mreq)))
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+#else
+ (void) fd;
+ (void) addr;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "IPv6 support not available");
+#endif /* HAVE_INET6 */
+#else
+ (void) fd;
+ (void) addr;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "socket options not supported");
+#endif /* HAVE_SETSOCKOPT */
}
-/* end of file */
+static uint32_t getif_address (JNIEnv *env, const char *ifname);
+static int getif_index (JNIEnv *env, const char *ifname);
+
+/*
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: joinGroup
+ * Signature: (I[BILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_joinGroup (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jbyteArray addr,
+ jstring ifname)
+{
+#ifdef HAVE_SETSOCKOPT
+ struct ip_mreq maddr;
+ jbyte *addr_elems;
+ const char *str_ifname;
+
+ if (ifname != NULL)
+ {
+ str_ifname = JCL_jstring_to_cstring(env, ifname);
+ maddr.imr_interface.s_addr = getif_address (env, str_ifname);
+ JCL_free_cstring(env, ifname, str_ifname);
+
+ if ((*env)->ExceptionCheck (env))
+ return;
+ }
+ else
+ maddr.imr_interface.s_addr = INADDR_ANY;
+
+ addr_elems = (*env)->GetByteArrayElements (env, addr, NULL);
+ if (addr_elems == NULL)
+ return;
+
+ maddr.imr_multiaddr.s_addr = * ((uint32_t *) addr_elems);
+
+ (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT);
+
+ if (-1 == setsockopt (fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ &maddr, sizeof (struct ip_mreq)))
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+
+#else
+ (void) fd;
+ (void) addr;
+ (void) ifname;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "socket options not supported");
+#endif /* HAVE_SETSOCKOPT */
+}
+
+/*
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: joinGroup6
+ * Signature: (I[BILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_joinGroup6 (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jbyteArray addr,
+ jstring ifname)
+{
+#ifdef HAVE_SETSOCKOPT
+#ifdef HAVE_INET6
+ struct ipv6_mreq maddr;
+ jbyte *addr_elems;
+ const char *str_ifname;
+
+ if (ifname == NULL)
+ {
+ str_ifname = JCL_jstring_to_cstring(env, ifname);
+ maddr.ipv6mr_interface = getif_index (env, str_ifname);
+ JCL_free_cstring(env, ifname, str_ifname);
+
+ if ((*env)->ExceptionCheck (env))
+ return;
+ }
+ else
+ maddr.ipv6mr_interface = 0;
+
+ addr_elems = (*env)->GetByteArrayElements (env, addr, NULL);
+ if (addr_elems == NULL)
+ return;
+
+ memcpy (&(maddr.ipv6mr_multiaddr.s6_addr), addr_elems, 16);
+
+ (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT);
+
+ if (-1 == setsockopt (fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
+ &maddr, sizeof (struct ipv6_mreq)))
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+#else
+ (void) fd;
+ (void) addr;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "IPv6 support not available");
+#endif /* HAVE_INET6 */
+#else
+ (void) fd;
+ (void) addr;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "socket options not supported");
+#endif /* HAVE_SETSOCKOPT */
+}
+
+/*
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: leaveGroup
+ * Signature: (I[BILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_leaveGroup (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jbyteArray addr,
+ jstring ifname)
+{
+#ifdef HAVE_SETSOCKOPT
+ struct ip_mreq maddr;
+ jbyte *addr_elems;
+ const char *str_ifname;
+
+ if (ifname != NULL)
+ {
+ str_ifname = JCL_jstring_to_cstring(env, ifname);
+ maddr.imr_interface.s_addr = getif_address (env, str_ifname);
+ JCL_free_cstring(env, ifname, str_ifname);
+
+ if ((*env)->ExceptionCheck (env))
+ return;
+ }
+ else
+ maddr.imr_interface.s_addr = INADDR_ANY;
+
+ addr_elems = (*env)->GetByteArrayElements (env, addr, NULL);
+ if (addr_elems == NULL)
+ return;
+
+ maddr.imr_multiaddr.s_addr = * ((uint32_t *) addr_elems);
+
+ (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT);
+
+ if (-1 == setsockopt (fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+ &maddr, sizeof (struct ip_mreq)))
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+#else
+ (void) fd;
+ (void) addr;
+ (void) ifname;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "socket options not supported");
+#endif /* HAVE_SETSOCKOPT */
+}
+
+/*
+ * Class: gnu_java_net_VMPlainSocketImpl
+ * Method: leaveGroup6
+ * Signature: (I[BILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_net_VMPlainSocketImpl_leaveGroup6 (JNIEnv *env,
+ jclass c __attribute__((unused)),
+ jint fd, jbyteArray addr,
+ jstring ifname)
+{
+#ifdef HAVE_SETSOCKOPT
+#ifdef HAVE_INET6
+ struct ipv6_mreq maddr;
+ jbyte *addr_elems;
+ const char *str_ifname;
+
+ if (ifname == NULL)
+ {
+ str_ifname = JCL_jstring_to_cstring(env, ifname);
+ maddr.ipv6mr_interface = getif_index (env, str_ifname);
+ JCL_free_cstring(env, ifname, str_ifname);
+
+ if ((*env)->ExceptionCheck (env))
+ return;
+ }
+ else
+ maddr.ipv6mr_interface = 0;
+
+ addr_elems = (*env)->GetByteArrayElements (env, addr, NULL);
+ if (addr_elems == NULL)
+ return;
+
+ memcpy (&(maddr.ipv6mr_multiaddr.s6_addr), addr_elems, 16);
+
+ (*env)->ReleaseByteArrayElements (env, addr, addr_elems, JNI_ABORT);
+
+ if (-1 == setsockopt (fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
+ &maddr, sizeof (struct ipv6_mreq)))
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+#else
+ (void) fd;
+ (void) addr;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "IPv6 support not available");
+#endif /* HAVE_INET6 */
+#else
+ (void) fd;
+ (void) addr;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "socket options not supported");
+#endif /* HAVE_SETSOCKOPT */
+}
+
+static uint32_t
+getif_address (JNIEnv *env, const char *ifname)
+{
+#if defined (HAVE_IFADDRS_H) && defined (HAVE_GETIFADDRS)
+ struct ifaddrs *ifaddrs, *i;
+ uint32_t addr = 0;
+ int foundaddr = 0;
+
+ if (getifaddrs (&ifaddrs) == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return 0;
+ }
+
+ for (i = ifaddrs; i != NULL; i = i->ifa_next)
+ {
+ if (strcmp (ifname, i->ifa_name) == 0)
+ {
+ /* Matched the name; see if there is an IPv4 address. */
+ if (i->ifa_addr->sa_family == AF_INET)
+ {
+ foundaddr = 1;
+ addr = ((struct sockaddr_in *) i->ifa_addr)->sin_addr.s_addr;
+ break;
+ }
+ }
+ }
+
+ if (!foundaddr)
+ JCL_ThrowException (env, SOCKET_EXCEPTION, "interface has no IPv4 address");
+
+ freeifaddrs (ifaddrs);
+
+ return addr;
+#else
+ (void) ifname;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "getifaddrs not available");
+ return 0;
+#endif /* HAVE_IFADDRS_H && HAVE_GETIFADDRS */
+}
+
+static int
+getif_index (JNIEnv *env, const char *ifname)
+{
+#if defined (HAVE_IFADDRS_H) && defined (HAVE_GETIFADDRS)
+ struct ifaddrs *ifaddrs, *i;
+ char *lastname = NULL;
+ int index = 1;
+ int foundname = 0;
+
+ if (getifaddrs (&ifaddrs) == -1)
+ {
+ JCL_ThrowException (env, SOCKET_EXCEPTION, strerror (errno));
+ return -1;
+ }
+
+ lastname = ifaddrs->ifa_name;
+ for (i = ifaddrs; i != NULL; i = i->ifa_next)
+ {
+ if (strcmp (lastname, ifaddrs->ifa_name) != 0)
+ {
+ lastname = ifaddrs->ifa_name;
+ index++;
+ }
+ if (strcmp (ifname, ifaddrs->ifa_name) == 0)
+ {
+ foundname = 1;
+ break;
+ }
+ }
+
+ if (!foundname)
+ JCL_ThrowException (env, SOCKET_EXCEPTION,
+ "no interface with that name");
+
+ freeifaddrs (ifaddrs);
+
+ return index;
+#else
+ (void) ifname;
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "getifaddrs not available");
+ return -1;
+#endif /* HAVE_GETIFADDRS */
+}
diff --git a/libjava/classpath/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c b/libjava/classpath/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c
index 35fb6bcdcc7..f2b2f8e63b8 100644
--- a/libjava/classpath/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c
+++ b/libjava/classpath/native/jni/java-net/gnu_java_net_local_LocalSocketImpl.c
@@ -38,9 +38,7 @@ exception statement from your version. */
#define _GNU_SOURCE
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif /* HAVE_CONFIG_H */
#include <gnu_java_net_local_LocalSocketImpl.h>
diff --git a/libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c b/libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c
index 86ac06e6f79..fc921ecef1f 100644
--- a/libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c
+++ b/libjava/classpath/native/jni/java-net/java_net_VMInetAddress.c
@@ -45,13 +45,10 @@ exception statement from your version. */
#include <jni.h>
#include <jcl.h>
+#include "cpnative.h"
+#include "cpnet.h"
#include "javanet.h"
-#include "target_native.h"
-#ifndef WITHOUT_NETWORK
-#include "target_native_network.h"
-#endif /* WITHOUT_NETWORK */
-
#include "java_net_VMInetAddress.h"
/*************************************************************************/
@@ -69,8 +66,8 @@ Java_java_net_VMInetAddress_getLocalHostname (JNIEnv * env,
jstring retval;
#ifndef WITHOUT_NETWORK
- TARGET_NATIVE_NETWORK_GET_HOSTNAME (hostname, sizeof (hostname), result);
- if (result != TARGET_NATIVE_OK)
+ result = cpnet_getHostname (env, hostname, sizeof (hostname));
+ if (result != CPNATIVE_OK)
{
strcpy (hostname, "localhost");
}
@@ -94,6 +91,7 @@ Java_java_net_VMInetAddress_lookupInaddrAny (JNIEnv * env,
__attribute__ ((__unused__)))
{
jarray IParray;
+ cpnet_address *addr;
jbyte *octets;
/* Allocate an array for the IP address */
@@ -108,11 +106,10 @@ Java_java_net_VMInetAddress_lookupInaddrAny (JNIEnv * env,
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);
+ addr = cpnet_newIPV4Address (env);
+ cpnet_setIPV4Any (addr);
+ cpnet_IPV4AddressToBytes (addr, octets);
+ cpnet_freeAddress (env, addr);
#else /* not WITHOUT_NETWORK */
octets[0] = 0;
octets[1] = 0;
@@ -120,6 +117,8 @@ Java_java_net_VMInetAddress_lookupInaddrAny (JNIEnv * env,
octets[3] = 0;
#endif /* not WITHOUT_NETWORK */
+ (*env)->ReleaseByteArrayElements (env, IParray, octets, 0);
+
return (IParray);
}
@@ -138,14 +137,14 @@ Java_java_net_VMInetAddress_getHostByAddr (JNIEnv * env,
#ifndef WITHOUT_NETWORK
jbyte *octets;
jsize len;
- int addr;
+ cpnet_address *addr;
char hostname[255];
int result;
jstring retval;
/* Grab the byte[] array with the IP out of the input data */
len = (*env)->GetArrayLength (env, arr);
- if (len != 4)
+ if (len != 4 && len != 16)
{
JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
return (jstring) NULL;
@@ -158,21 +157,31 @@ Java_java_net_VMInetAddress_getHostByAddr (JNIEnv * env,
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);
+ switch (len)
+ {
+ case 4:
+ addr = cpnet_newIPV4Address(env);
+ cpnet_bytesToIPV4Address (addr, octets);
+ break;
+ case 16:
+ addr = cpnet_newIPV6Address(env);
+ cpnet_bytesToIPV6Address (addr, octets);
+ break;
+ default:
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
+ return (jstring) NULL;
+
+ }
/* 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)
+ result = cpnet_getHostByAddr (env, addr, hostname, sizeof (hostname));
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return (jstring) NULL;
}
@@ -194,16 +203,14 @@ Java_java_net_VMInetAddress_getHostByName (JNIEnv * env,
{
#ifndef WITHOUT_NETWORK
const char *hostname;
-/* FIXME: limitation of max. 64 addresses - how to make it more flexibale? */
- int addresses[64];
+ cpnet_address **addresses;
jsize addresses_count;
int result;
jclass arr_class;
jobjectArray addrs;
- int i;
+ jint i;
jbyte *octets;
jarray ret_octets;
- int max_addresses;
/* Grab the hostname string */
hostname = (*env)->GetStringUTFChars (env, host, 0);
@@ -213,12 +220,8 @@ Java_java_net_VMInetAddress_getHostByName (JNIEnv * env,
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)
+ result = cpnet_getHostByName (env, hostname, &addresses, &addresses_count);
+ if (result != CPNATIVE_OK || addresses_count == 0)
{
JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, (char *) hostname);
return (jobjectArray) NULL;
@@ -242,28 +245,144 @@ Java_java_net_VMInetAddress_getHostByName (JNIEnv * env,
/* Now loop and copy in each address */
for (i = 0; i < addresses_count; i++)
{
- ret_octets = (*env)->NewByteArray (env, 4);
- if (!ret_octets)
+ if (cpnet_isIPV6Address (addresses[i]))
+ {
+ ret_octets = (*env)->NewByteArray (env, 16);
+
+ if (!ret_octets)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ cpnet_freeAddresses (env, addresses, addresses_count);
+ return (jobjectArray) NULL;
+ }
+
+ octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
+
+ cpnet_IPV6AddressToBytes (addresses[i], octets);
+
+ (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
+
+ (*env)->SetObjectArrayElement (env, addrs, i, ret_octets);
+ }
+ else if (cpnet_isIPV4Address (addresses[i]))
+ {
+ ret_octets = (*env)->NewByteArray (env, 4);
+
+ if (!ret_octets)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ cpnet_freeAddresses (env, addresses, addresses_count);
+ return (jobjectArray) NULL;
+ }
+
+ octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
+
+ cpnet_IPV4AddressToBytes (addresses[i], octets);
+
+ (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
+
+ (*env)->SetObjectArrayElement (env, addrs, i, ret_octets);
+ }
+ else
{
JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ cpnet_freeAddresses (env, addresses, addresses_count);
return (jobjectArray) NULL;
}
+ }
+
+ cpnet_freeAddresses (env, addresses, addresses_count);
+
+ return (addrs);
+#else /* not WITHOUT_NETWORK */
+ return (jobjectArray) NULL;
+#endif /* not WITHOUT_NETWORK */
+}
+
+/*************************************************************************/
+
+/*
+ * Return the IP address represented by a literal address.
+ * Will return null if the literal address is not valid.
+ */
+JNIEXPORT jbyteArray JNICALL
+Java_java_net_VMInetAddress_aton (JNIEnv *env,
+ jclass class
+ __attribute__ ((__unused__)),
+ jstring host)
+{
+#ifndef WITHOUT_NETWORK
+ const char *hostname;
+ cpnet_address *address;
+ int result;
+ jbyte *octets;
+ jbyteArray ret_octets;
+
+ hostname = (*env)->GetStringUTFChars (env, host, 0);
+ if (!hostname)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Null hostname");
+ return (jbyteArray) NULL;
+ }
+
+ result = cpnet_aton (env, hostname, &address);
+ if (result != CPNATIVE_OK)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ if (address)
+ cpnet_freeAddress (env, address);
+ return (jbyteArray) NULL;
+ }
+ if (!address)
+ return (jbyteArray) NULL;
+ if (cpnet_isIPV6Address (address))
+ {
+ ret_octets = (jbyteArray) (*env)->NewByteArray (env, 16);
+
+ if (!ret_octets)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ cpnet_freeAddress (env, address);
+ return (jbyteArray) 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]);
+ cpnet_IPV6AddressToBytes (address, octets);
(*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
+ }
+ else if (cpnet_isIPV4Address (address))
+ {
+ ret_octets = (jbyteArray) (*env)->NewByteArray (env, 4);
+
+ if (!ret_octets)
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ cpnet_freeAddress (env, address);
+ return (jbyteArray) NULL;
+ }
+
+ octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
+
+ cpnet_IPV4AddressToBytes (address, octets);
- (*env)->SetObjectArrayElement (env, addrs, i, ret_octets);
+ (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
+ }
+ else
+ {
+ JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
+ cpnet_freeAddress (env, address);
+ return (jbyteArray) NULL;
}
- return (addrs);
+ cpnet_freeAddress (env, address);
+
+ return (ret_octets);
+
#else /* not WITHOUT_NETWORK */
- return (jobjectArray) NULL;
+ return (jbyteArray) NULL;
#endif /* not WITHOUT_NETWORK */
}
diff --git a/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c b/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c
index f05e9fcc5a2..b51bf68ecee 100644
--- a/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c
+++ b/libjava/classpath/native/jni/java-net/java_net_VMNetworkInterface.c
@@ -35,9 +35,17 @@ 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 */
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif /* HAVE_CONFIG_H */
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#endif
+#include <netinet/in.h>
+#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -47,19 +55,197 @@ exception statement from your version. */
#include "java_net_VMNetworkInterface.h"
-#include "javanet.h"
+
+static jmethodID java_net_VMNetworkInterface_init;
+static jmethodID java_net_VMNetworkInterface_addAddress;
/*
- * Returns all local network interfaces as vector
+ * Initialize our static method ID's.
+ *
+ * Class: java_net_VMNetworkInterface
+ * Method: initIds
+ * Signature: ()V
*/
-JNIEXPORT jobject JNICALL
-Java_java_net_VMNetworkInterface_getInterfaces (JNIEnv * env,
- jclass class
- __attribute__ ((__unused__)))
+JNIEXPORT void JNICALL
+Java_java_net_VMNetworkInterface_initIds (JNIEnv *env, jclass clazz)
+{
+ java_net_VMNetworkInterface_init =
+ (*env)->GetMethodID (env, clazz, "<init>", "(Ljava/lang/String;)V");
+ if (java_net_VMNetworkInterface_init == NULL)
+ {
+ if (!(*env)->ExceptionCheck (env))
+ JCL_ThrowException (env, "java/lang/NoSuchMethodError",
+ "VMNetworkinterface.addAddress");
+ return;
+ }
+ java_net_VMNetworkInterface_addAddress =
+ (*env)->GetMethodID (env, clazz, "addAddress", "(Ljava/nio/ByteBuffer;)V");
+ if (java_net_VMNetworkInterface_addAddress == NULL)
+ {
+ if (!(*env)->ExceptionCheck (env))
+ JCL_ThrowException (env, "java/lang/NoSuchMethodError",
+ "VMNetworkinterface.addAddress");
+ }
+}
+
+struct netif_entry
+{
+ char *name;
+ jobject netif;
+ int numaddrs;
+ struct netif_entry *next;
+};
+
+static void
+free_netif_list (JNIEnv *env, struct netif_entry *list)
{
- JCL_ThrowException (env, IO_EXCEPTION,
- "java.net.VMNetworkInterface.getInterfaces(): not implemented");
- return 0;
+ while (list != NULL)
+ {
+ struct netif_entry *e = list->next;
+ JCL_free (env, list);
+ list = e;
+ }
+}
+
+/*
+ * Returns all local network interfaces as an array.
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_java_net_VMNetworkInterface_getVMInterfaces (JNIEnv * env, jclass clazz)
+{
+#if defined (HAVE_IFADDRS_H) && defined (HAVE_GETIFADDRS)
+ struct ifaddrs *ifaddrs, *i;
+ struct netif_entry *iflist = NULL, *e;
+ jobjectArray netifs;
+ int numifs = 0;
+ int k;
+
+ if (getifaddrs (&ifaddrs) == -1)
+ {
+ JCL_ThrowException (env, "java/net/SocketException", strerror (errno));
+ return NULL;
+ }
+
+ for (i = ifaddrs; i != NULL; i = i->ifa_next)
+ {
+ if (iflist == NULL)
+ {
+ iflist = JCL_malloc (env, sizeof (struct netif_entry));
+ if (iflist == NULL)
+ {
+ freeifaddrs (ifaddrs);
+ return NULL;
+ }
+ iflist->name = i->ifa_name;
+ iflist->numaddrs = 0;
+ iflist->next = NULL;
+ iflist->netif = (*env)->NewObject (env, clazz, java_net_VMNetworkInterface_init,
+ (*env)->NewStringUTF (env, i->ifa_name));
+ if (iflist->netif == NULL)
+ {
+ freeifaddrs (ifaddrs);
+ JCL_free (env, iflist);
+ return NULL;
+ }
+ e = iflist;
+ }
+ else
+ {
+ struct netif_entry *p = NULL;
+ for (e = iflist; e != NULL; e = e->next)
+ {
+ if (strcmp (e->name, i->ifa_name) == 0)
+ break;
+ p = e;
+ }
+
+ if (e == NULL)
+ {
+ p->next = (struct netif_entry *) JCL_malloc (env, sizeof (struct netif_entry));
+ if (p->next == NULL)
+ {
+ free_netif_list (env, iflist);
+ freeifaddrs (ifaddrs);
+ return NULL;
+ }
+ e = p->next;
+ e->name = i->ifa_name;
+ e->numaddrs = 0;
+ e->next = NULL;
+ e->netif = (*env)->NewObject (env, clazz, java_net_VMNetworkInterface_init,
+ (*env)->NewStringUTF (env, i->ifa_name));
+ if (e->netif == NULL)
+ {
+ free_netif_list (env, iflist);
+ freeifaddrs (ifaddrs);
+ return NULL;
+ }
+ }
+ }
+
+ if (i->ifa_addr == NULL)
+ continue;
+
+ if (i->ifa_addr->sa_family == AF_INET)
+ {
+ struct sockaddr_in *sin = (struct sockaddr_in *) i->ifa_addr;
+ jobject buffer = (*env)->NewDirectByteBuffer (env, &(sin->sin_addr.s_addr), 4);
+ (*env)->CallVoidMethod (env, e->netif, java_net_VMNetworkInterface_addAddress,
+ buffer);
+ if ((*env)->ExceptionCheck (env))
+ {
+ free_netif_list (env, iflist);
+ freeifaddrs (ifaddrs);
+ return NULL;
+ }
+ (*env)->DeleteLocalRef (env, buffer);
+ e->numaddrs++;
+ }
+#ifdef HAVE_INET6
+ else if (i->ifa_addr->sa_family == AF_INET6)
+ {
+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *) i->ifa_addr;
+ jobject buffer = (*env)->NewDirectByteBuffer (env, &(sin->sin6_addr.s6_addr), 16);
+ (*env)->CallVoidMethod (env, e->netif, java_net_VMNetworkInterface_addAddress,
+ buffer);
+ if ((*env)->ExceptionCheck (env))
+ {
+ free_netif_list (env, iflist);
+ freeifaddrs (ifaddrs);
+ return NULL;
+ }
+ (*env)->DeleteLocalRef (env, buffer);
+ e->numaddrs++;
+ }
+#endif /* HAVE_INET6 */
+ }
+
+ /* Count how many interfaces we have that have addresses. */
+ for (e = iflist; e != NULL; e = e->next)
+ {
+ if (e->numaddrs != 0)
+ numifs++;
+ }
+
+ netifs = (*env)->NewObjectArray (env, numifs, clazz, NULL);
+ k = 0;
+ for (e = iflist; e != NULL && k < numifs; e = e->next)
+ {
+ if (e->numaddrs != 0)
+ {
+ (*env)->SetObjectArrayElement (env, netifs, k, e->netif);
+ (*env)->DeleteLocalRef (env, e->netif);
+ k++;
+ }
+ }
+
+ free_netif_list (env, iflist);
+ freeifaddrs (ifaddrs);
+ return netifs;
+#else
+ JCL_ThrowException (env, "java/net/SocketException", "getifaddrs not supported");
+ return NULL;
+#endif /* HAVE_GETIFADDRS */
}
/* end of file */
diff --git a/libjava/classpath/native/jni/java-net/javanet.c b/libjava/classpath/native/jni/java-net/javanet.c
index e500c608431..1d2f7202a17 100644
--- a/libjava/classpath/native/jni/java-net/javanet.c
+++ b/libjava/classpath/native/jni/java-net/javanet.c
@@ -45,12 +45,10 @@ exception statement from your version. */
#include <jni.h>
#include <jcl.h>
-#include "javanet.h"
+#include "cpnative.h"
+#include "cpnet.h"
-#include "target_native.h"
-#ifndef WITHOUT_NETWORK
-#include "target_native_network.h"
-#endif /* WITHOUT_NETWORK */
+#include "javanet.h"
#ifndef WITHOUT_NETWORK
/* Need to have some value for SO_TIMEOUT */
@@ -234,23 +232,20 @@ _javanet_create_integer (JNIEnv * env, jint val)
/*
* Builds an InetAddress object from a 32 bit address in host byte order
*/
-static jobject
-_javanet_create_inetaddress (JNIEnv * env, int netaddr)
+jobject
+_javanet_create_inetaddress (JNIEnv * env, cpnet_address *netaddr)
{
#ifndef WITHOUT_NETWORK
- unsigned char octets[4];
- char buf[16];
+ jbyte octets[4];
+ char buf[64];
jclass ia_cls;
jmethodID mid;
jstring ip_str;
jobject ia;
/* 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]);
+ cpnet_IPV4AddressToBytes(netaddr, octets);
+ sprintf (buf, "%d.%d.%d.%d", (int) (unsigned char)octets[0], (int)(unsigned char)octets[1], (int)(unsigned char)octets[2], (int)(unsigned char)octets[3]);
DBG ("_javanet_create_inetaddress(): Created ip addr string\n");
/* Get an InetAddress object for this IP */
@@ -320,7 +315,7 @@ _javanet_set_remhost_addr (JNIEnv * env, jobject this, jobject ia)
* InetAddress for the specified addr
*/
static void
-_javanet_set_remhost (JNIEnv * env, jobject this, int netaddr)
+_javanet_set_remhost (JNIEnv * env, jobject this, cpnet_address *netaddr)
{
jobject ia;
@@ -338,19 +333,20 @@ _javanet_set_remhost (JNIEnv * env, jobject this, int netaddr)
/*************************************************************************/
/*
- * Returns a 32 bit Internet address for the passed in InetAddress object
+ * Returns an Internet address for the passed in InetAddress object
*/
-int
-_javanet_get_netaddr (JNIEnv * env, jobject addr)
+cpnet_address *
+_javanet_get_ip_netaddr (JNIEnv * env, jobject addr)
{
#ifndef WITHOUT_NETWORK
jclass cls = 0;
jmethodID mid;
jarray arr = 0;
jbyte *octets;
- int netaddr, len;
+ cpnet_address *netaddr;
+ jint len;
- DBG ("_javanet_get_netaddr(): Entered _javanet_get_netaddr\n");
+ DBG ("_javanet_get_ip_netaddr(): Entered _javanet_get_ip_netaddr\n");
if (addr == NULL)
{
@@ -368,36 +364,51 @@ _javanet_get_netaddr (JNIEnv * env, jobject addr)
if (mid == NULL)
return 0;
- DBG ("_javanet_get_netaddr(): Got getAddress method\n");
+ DBG ("_javanet_get_ip_netaddr(): Got getAddress method\n");
arr = (*env)->CallObjectMethod (env, addr, mid);
if (arr == NULL)
return 0;
- DBG ("_javanet_get_netaddr(): Got the address\n");
+ DBG ("_javanet_get_ip_netaddr(): Got the address\n");
- /* Turn the IP address into a 32 bit Internet address in network byte order */
+ /* Turn the IP address into a system cpnet address.
+ * If the length is 4 then it is an IPV4 address, if it
+ * is 16 then it is an IPV6 address else it is an InternError. */
len = (*env)->GetArrayLength (env, arr);
- if (len != 4)
+ if (len != 4 && len != 16)
{
JCL_ThrowException (env, IO_EXCEPTION, "Internal Error");
return 0;
}
- DBG ("_javanet_get_netaddr(): Length ok\n");
+ DBG ("_javanet_get_ip_netaddr(): Length ok\n");
octets = (*env)->GetByteArrayElements (env, arr, 0);
if (octets == NULL)
return 0;
- DBG ("_javanet_get_netaddr(): Grabbed bytes\n");
+ DBG ("_javanet_get_ip_netaddr(): Grabbed bytes\n");
- TARGET_NATIVE_NETWORK_IPADDRESS_BYTES_TO_INT (octets[0],
- octets[1],
- octets[2],
- octets[3], netaddr);
+ switch (len)
+ {
+ case 4:
+ netaddr = cpnet_newIPV4Address(env);
+ cpnet_bytesToIPV4Address(netaddr, octets);
+ break;
+ case 16:
+ netaddr = cpnet_newIPV6Address(env);
+ cpnet_bytesToIPV6Address(netaddr, octets);
+ break;
+ default:
+ /* This should not happen as we have checked before.
+ * But that way we shut the compiler warnings */
+ JCL_ThrowException (env, IO_EXCEPTION, "Internal Error");
+ return 0;
+
+ }
(*env)->ReleaseByteArrayElements (env, arr, octets, 0);
- DBG ("_javanet_get_netaddr(): Done getting addr\n");
+ DBG ("_javanet_get_ip_netaddr(): Done getting addr\n");
return netaddr;
#else /* not WITHOUT_NETWORK */
@@ -419,29 +430,29 @@ _javanet_create (JNIEnv * env, jobject this, jboolean stream)
if (stream)
{
/* create a stream socket */
- TARGET_NATIVE_NETWORK_SOCKET_OPEN_STREAM (fd, result);
- if (result != TARGET_NATIVE_OK)
+ result = cpnet_openSocketStream(env, &fd, AF_INET);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, IO_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return;
}
}
else
{
/* create a datagram socket, set broadcast option */
- TARGET_NATIVE_NETWORK_SOCKET_OPEN_DATAGRAM (fd, result);
- if (result != TARGET_NATIVE_OK)
+ result = cpnet_openSocketDatagram (env, &fd, AF_INET);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, IO_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return;
}
- TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_BROADCAST (fd, 1, result);
- if (result != TARGET_NATIVE_OK)
+ result = cpnet_setBroadcast(env, fd, 1);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, IO_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return;
}
}
@@ -458,13 +469,11 @@ _javanet_create (JNIEnv * env, jobject this, jboolean stream)
/* 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))
+ result = cpnet_close(env, fd);
+ if (result != CPNATIVE_OK && result != CPNATIVE_EINTR)
return;
}
- while (result != TARGET_NATIVE_OK);
+ while (result != CPNATIVE_OK);
return;
}
@@ -498,18 +507,16 @@ _javanet_close (JNIEnv * env, jobject this, int stream)
"native_fd", -1);
do
{
- TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
- if (result != TARGET_NATIVE_OK)
+ result = cpnet_close (env, fd);
+ if (result != CPNATIVE_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)
+ if (result != CPNATIVE_EINTR && result != ENOTCONN && result != ECONNRESET && result != EBADF)
JCL_ThrowException (env, IO_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
}
}
- while (error == TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL);
+ while (error == CPNATIVE_EINTR);
#else /* not WITHOUT_NETWORK */
#endif /* not WITHOUT_NETWORK */
@@ -525,20 +532,24 @@ _javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port,
jboolean stream)
{
#ifndef WITHOUT_NETWORK
- int netaddr, fd;
+ cpnet_address *netaddr;
+ int fd;
int result;
- int local_address, local_port;
- int remote_address, remote_port;
+ cpnet_address *local_addr;
+ cpnet_address *remote_addr;
DBG ("_javanet_connect(): Entered _javanet_connect\n");
/* Pre-process input variables */
- netaddr = _javanet_get_netaddr (env, addr);
+ netaddr = _javanet_get_ip_netaddr (env, addr);
if ((*env)->ExceptionOccurred (env))
return;
if (port == -1)
port = 0;
+
+ cpnet_addressSetPort(netaddr, port);
+
DBG ("_javanet_connect(): Got network address\n");
/* Grab the real socket file descriptor */
@@ -554,29 +565,27 @@ _javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port,
/* 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))
+ result = cpnet_connect (env, fd, netaddr);
+ if (result != CPNATIVE_OK && result != CPNATIVE_EINTR)
{
JCL_ThrowException (env, CONNECT_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return;
}
}
- while (result != TARGET_NATIVE_OK);
-
+ while (result != CPNATIVE_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)
+ result = cpnet_getLocalAddr (env, fd, &local_addr);
+ if (result != CPNATIVE_OK)
{
+ cpnet_freeAddress(env, netaddr);
JCL_ThrowException (env, IO_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
/* We don't care whether this succeeds. close() will cleanup later. */
- TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ cpnet_close (env, fd);
return;
}
@@ -584,63 +593,72 @@ _javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port,
if ((*env)->ExceptionOccurred (env))
{
/* We don't care whether this succeeds. close() will cleanup later. */
- TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ cpnet_freeAddress(env, netaddr);
+ cpnet_freeAddress(env, local_addr);
+ cpnet_close (env, fd);
return;
}
DBG ("_javanet_connect(): Created fd\n");
if (stream)
_javanet_set_int_field (env, this, "java/net/SocketImpl", "localport",
- local_port);
+ cpnet_addressGetPort(local_addr));
else
_javanet_set_int_field (env, this, "java/net/DatagramSocketImpl",
- "localPort", local_port);
+ "localPort", cpnet_addressGetPort(local_addr));
+ cpnet_freeAddress (env, local_addr);
if ((*env)->ExceptionOccurred (env))
{
/* We don't care whether this succeeds. close() will cleanup later. */
- TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ cpnet_freeAddress(env, netaddr);
+ cpnet_close (env, fd);
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)
+ result = cpnet_getRemoteAddr (env, fd, &remote_addr);
+ if (result != CPNATIVE_OK)
{
+ cpnet_freeAddress(env, netaddr);
JCL_ThrowException (env, IO_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
/* We don't care whether this succeeds. close() will cleanup later. */
- TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ cpnet_close (env, fd);
return;
}
if (stream)
{
- if (remote_address == netaddr)
+ if (cpnet_isAddressEqual(remote_addr, netaddr))
{
_javanet_set_remhost_addr (env, this, addr);
}
else
{
- _javanet_set_remhost (env, this, remote_address);
+ _javanet_set_remhost (env, this, remote_addr);
}
+ cpnet_freeAddress(env, netaddr);
+
if ((*env)->ExceptionOccurred (env))
{
/* We don't care whether this succeeds. close() will cleanup later.
*/
- TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ cpnet_freeAddress (env, remote_addr);
+ cpnet_close (env, fd);
return;
}
DBG ("_javanet_connect(): Set the remote host\n");
_javanet_set_int_field (env, this, "java/net/SocketImpl", "port",
- remote_port);
+ cpnet_addressGetPort(remote_addr));
+ cpnet_freeAddress (env, remote_addr);
+
if ((*env)->ExceptionOccurred (env))
{
/* We don't care whether this succeeds. close() will cleanup later.
*/
- TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+ cpnet_close (env, fd);
return;
}
DBG ("_javanet_connect(): Set the remote port\n");
@@ -661,98 +679,59 @@ _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;
+ cpnet_address *tmpaddr;
+ cpnet_address *local_addr;
int result;
- int local_address, local_port;
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 */
+
+ /* Grab the real 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");
+ "Internal error: _javanet_connect(): 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));
+ cpnet_setReuseAddress (env, fd, 1);
+ /* Get the address to connect to */
+ tmpaddr = _javanet_get_ip_netaddr (env, addr);
+ if ((*env)->ExceptionOccurred (env))
+ return;
- /* 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)
+ cpnet_addressSetPort (tmpaddr, port);
+ result = cpnet_bind(env, fd, tmpaddr);
+ cpnet_freeAddress (env, tmpaddr);
+ if (result != CPNATIVE_OK)
{
- char *errorstr = TARGET_NATIVE_LAST_ERROR_STRING ();
- (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
-
JCL_ThrowException (env, BIND_EXCEPTION,
- errorstr);
+ cpnative_getErrorString (result));
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)
+ result = cpnet_getLocalAddr (env, fd, &local_addr);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, IO_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return;
}
if (stream)
_javanet_set_int_field (env, this, "java/net/SocketImpl",
- "localport", local_port);
+ "localport", cpnet_addressGetPort (local_addr));
else
_javanet_set_int_field (env, this, "java/net/DatagramSocketImpl",
- "localPort", local_port);
+ "localPort", cpnet_addressGetPort (local_addr));
DBG ("_javanet_bind(): Past update port number\n");
+ cpnet_freeAddress (env, local_addr);
+
return;
#else /* not WITHOUT_NETWORK */
#endif /* not WITHOUT_NETWORK */
@@ -781,11 +760,11 @@ _javanet_listen (JNIEnv * env, jobject this, jint queuelen)
}
/* Start listening */
- TARGET_NATIVE_NETWORK_SOCKET_LISTEN (fd, queuelen, result);
- if (result != TARGET_NATIVE_OK)
+ result = cpnet_listen (env, fd, queuelen);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, IO_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return;
}
#else /* not WITHOUT_NETWORK */
@@ -804,8 +783,7 @@ _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;
+ cpnet_address *remote_addr, *local_addr;
/* Get the real file descriptor */
fd = _javanet_get_int_field (env, this, "native_fd");
@@ -819,24 +797,22 @@ _javanet_accept (JNIEnv * env, jobject this, jobject impl)
/* 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))
+ result = cpnet_accept (env, fd, &newfd);
+ if (result != CPNATIVE_OK && result != CPNATIVE_EINTR)
{
- if (TARGET_NATIVE_LAST_ERROR () == EAGAIN)
+ if (result == ETIMEDOUT || result == EAGAIN)
JCL_ThrowException (env, "java/net/SocketTimeoutException",
- "Timeout");
+ "Accept operation timed out");
else
JCL_ThrowException (env, IO_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return;
}
}
- while (result != TARGET_NATIVE_OK);
+ while (result != CPNATIVE_OK);
/* Reset the inherited timeout. */
- TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_TIMEOUT (newfd, 0, result);
+ cpnet_setSocketTimeout (env, newfd, 0);
/* Populate instance variables */
_javanet_set_int_field (env, impl, "gnu/java/net/PlainSocketImpl",
@@ -847,24 +823,21 @@ _javanet_accept (JNIEnv * env, jobject this, jobject impl)
/* 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))
+ result = cpnet_close (env, newfd);
+ if (result != CPNATIVE_OK && result != CPNATIVE_EINTR)
return;
}
- while (result != TARGET_NATIVE_OK);
+ while (result != CPNATIVE_OK);
return;
}
- TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (newfd, local_address,
- local_port, result);
- if (result != TARGET_NATIVE_OK)
+ result = cpnet_getLocalAddr (env, newfd, &local_addr);
+ if (result != CPNATIVE_OK)
{
/* We don't care whether this succeeds. close() will cleanup later. */
- TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ cpnet_close (env, newfd);
JCL_ThrowException (env, IO_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return;
}
@@ -872,44 +845,47 @@ _javanet_accept (JNIEnv * env, jobject this, jobject impl)
if ((*env)->ExceptionOccurred (env))
{
/* We don't care whether this succeeds. close() will cleanup later. */
- TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ cpnet_freeAddress (env, local_addr);
+ cpnet_close (env, newfd);
return;
}
_javanet_set_int_field (env, impl, "java/net/SocketImpl", "localport",
- local_port);
+ cpnet_addressGetPort (local_addr));
+ cpnet_freeAddress (env, local_addr);
if ((*env)->ExceptionOccurred (env))
{
/* We don't care whether this succeeds. close() will cleanup later. */
- TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ cpnet_close (env, newfd);
return;
}
- TARGET_NATIVE_NETWORK_SOCKET_GET_REMOTE_INFO (newfd, remote_address,
- remote_port, result);
- if (result != TARGET_NATIVE_OK)
+ result = cpnet_getRemoteAddr (env, newfd, &remote_addr);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, IO_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
/* We don't care whether this succeeds. close() will cleanup later. */
- TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ cpnet_close (env, newfd);
return;
}
- _javanet_set_remhost (env, impl, remote_address);
+ _javanet_set_remhost (env, impl, remote_addr);
if ((*env)->ExceptionOccurred (env))
{
/* We don't care whether this succeeds. close() will cleanup later. */
- TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ cpnet_close (env, newfd);
+ cpnet_freeAddress (env, remote_addr);
return;
}
_javanet_set_int_field (env, impl, "java/net/SocketImpl", "port",
- remote_port);
+ cpnet_addressGetPort (remote_addr));
+ cpnet_freeAddress (env, remote_addr);
if ((*env)->ExceptionOccurred (env))
{
/* We don't care whether this succeeds. close() will cleanup later. */
- TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result);
+ cpnet_close (env, newfd);
return;
}
#else /* not WITHOUT_NETWORK */
@@ -934,13 +910,14 @@ _javanet_accept (JNIEnv * env, jobject this, jobject impl)
*/
int
_javanet_recvfrom (JNIEnv * env, jobject this, jarray buf, int offset,
- int len, int *addr, int *port)
+ int len, cpnet_address **addr)
{
#ifndef WITHOUT_NETWORK
int fd;
jbyte *p;
- int from_address, from_port;
- int received_bytes;
+ cpnet_address *from_addr;
+ jint received_bytes;
+ int result;
DBG ("_javanet_recvfrom(): Entered _javanet_recvfrom\n");
@@ -962,36 +939,26 @@ _javanet_recvfrom (JNIEnv * env, jobject this, jarray buf, int offset,
DBG ("_javanet_recvfrom(): Got buffer\n");
/* Read the data */
- from_address = 0;
- from_port = 0;
+ from_addr = NULL;
do
{
if (addr != NULL)
{
- TARGET_NATIVE_NETWORK_SOCKET_RECEIVE_WITH_ADDRESS_PORT (fd,
- p + offset,
- len,
- from_address,
- from_port,
- received_bytes);
+ result = cpnet_recvFrom (env, fd, p + offset, len, &from_addr, &received_bytes);
}
else
{
- TARGET_NATIVE_NETWORK_SOCKET_RECEIVE (fd, p + offset, len,
- received_bytes);
+ result = cpnet_recv (env, fd, p + offset, len, &received_bytes);
}
}
- while ((received_bytes == -1) &&
- (TARGET_NATIVE_LAST_ERROR () ==
- TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL));
-
- if (received_bytes == -1)
+ while (result == CPNATIVE_EINTR);
+ if (result != 0)
{
- if (TARGET_NATIVE_LAST_ERROR () == EAGAIN)
- JCL_ThrowException (env, "java/net/SocketTimeoutException", "Timeout");
+ if (result == EAGAIN || result == ETIMEDOUT)
+ JCL_ThrowException (env, "java/net/SocketTimeoutException", "Receive operation timed out");
else
JCL_ThrowException (env, IO_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
/* Cleanup and return. */
(*env)->ReleaseByteArrayElements (env, buf, p, 0);
@@ -1003,9 +970,7 @@ _javanet_recvfrom (JNIEnv * env, jobject this, jarray buf, int offset,
/* Handle return addr case */
if (addr != NULL)
{
- (*addr) = from_address;
- if (port != NULL)
- (*port) = from_port;
+ (*addr) = from_addr;
}
/* zero bytes received means recv() noticed the other side orderly
@@ -1013,7 +978,7 @@ _javanet_recvfrom (JNIEnv * env, jobject this, jarray buf, int offset,
if (received_bytes == 0)
received_bytes = -1;
- return (received_bytes);
+ return received_bytes;
#else /* not WITHOUT_NETWORK */
#endif /* not WITHOUT_NETWORK */
}
@@ -1031,12 +996,13 @@ _javanet_recvfrom (JNIEnv * env, jobject this, jarray buf, int offset,
*/
void
_javanet_sendto (JNIEnv * env, jobject this, jarray buf, int offset, int len,
- int addr, int port)
+ cpnet_address *addr)
{
#ifndef WITHOUT_NETWORK
int fd;
jbyte *p;
- int bytes_sent;
+ jint bytes_sent;
+ int result;
/* Get the real file descriptor */
fd = _javanet_get_int_field (env, this, "native_fd");
@@ -1056,26 +1022,30 @@ _javanet_sendto (JNIEnv * env, jobject this, jarray buf, int offset, int len,
while (len > 0)
{
/* Send the data */
- if (addr == 0)
+ if (addr == NULL)
{
DBG ("_javanet_sendto(): Sending....\n");
- TARGET_NATIVE_NETWORK_SOCKET_SEND (fd, p + offset, len, bytes_sent);
+ result = cpnet_send (env, 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);
+ result = cpnet_sendTo (env, fd, p + offset, len, addr, &bytes_sent);
}
+ if (result == EDESTADDRREQ)
+ {
+ JCL_ThrowException (env, NULL_EXCEPTION,
+ "Socket is not connected and no address is given");
+ break;
+ }
+
if (bytes_sent < 0)
{
- if (TARGET_NATIVE_LAST_ERROR ()
- != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)
+ if (result != CPNATIVE_EINTR)
{
JCL_ThrowException (env, IO_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
break;
}
}
@@ -1105,8 +1075,8 @@ _javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
int optval;
jclass cls;
jmethodID mid;
- int address;
- int result;
+ cpnet_address * address;
+ int result = CPNATIVE_OK;
/* Get the real file descriptor */
fd = _javanet_get_int_field (env, this, "native_fd");
@@ -1123,7 +1093,6 @@ _javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
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 */
@@ -1141,8 +1110,7 @@ _javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
if ((*env)->ExceptionOccurred (env))
return;
- TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_TCP_NODELAY (fd, optval,
- result);
+ result = cpnet_setSocketTCPNoDelay (env, fd, optval);
break;
/* SO_LINGER case. If val is a boolean, then it will always be set
@@ -1153,8 +1121,7 @@ _javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
if (mid)
{
/* We are disabling linger */
- TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_LINGER (fd, 1, 0,
- result);
+ result = cpnet_setLinger (env, fd, JNI_FALSE, 0);
}
else
{
@@ -1175,15 +1142,13 @@ _javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
if ((*env)->ExceptionOccurred (env))
return;
- TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_LINGER (fd, 0, optval,
- result);
+ result = cpnet_setLinger(env, fd, JNI_TRUE, optval);
}
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)
{
@@ -1196,10 +1161,7 @@ _javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
if ((*env)->ExceptionOccurred (env))
return;
- TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_TIMEOUT (fd, optval, result);
-#else
- result = TARGET_NATIVE_OK;
-#endif
+ result = cpnet_setSocketTimeout (env, fd, optval);
break;
case SOCKOPT_SO_SNDBUF:
@@ -1218,11 +1180,9 @@ _javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
return;
if (option_id == SOCKOPT_SO_SNDBUF)
- TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_SNDBUF (fd, optval,
- result);
+ result = cpnet_setSendBuf (env, fd, optval);
else
- TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_RCDBUF (fd, optval,
- result);
+ result = cpnet_setRecvBuf (env, fd, optval);
break;
/* TTL case. Val with be an Integer with the new time to live value */
@@ -1239,18 +1199,18 @@ _javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
if ((*env)->ExceptionOccurred (env))
return;
- TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_TTL (fd, optval, result);
+ result = cpnet_setTTL (env, fd, optval);
break;
/* Multicast Interface case - val is InetAddress object */
case SOCKOPT_IP_MULTICAST_IF:
- address = _javanet_get_netaddr (env, val);
+ address = _javanet_get_ip_netaddr (env, val);
if ((*env)->ExceptionOccurred (env))
return;
-
- TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_IP_MULTICAST_IF (fd, address,
- result);
+
+ result = cpnet_setMulticastIF (env, fd, address);
+ cpnet_freeAddress (env, address);
break;
case SOCKOPT_SO_REUSEADDR:
@@ -1267,8 +1227,7 @@ _javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
if ((*env)->ExceptionOccurred (env))
return;
- TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_REUSE_ADDRESS (fd, optval,
- result);
+ result = cpnet_setReuseAddress (env, fd, optval);
break;
case SOCKOPT_SO_KEEPALIVE:
@@ -1285,7 +1244,7 @@ _javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
if ((*env)->ExceptionOccurred (env))
return;
- TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_KEEP_ALIVE (fd, optval, result);
+ result = cpnet_setKeepAlive (env, fd, optval);
break;
case SOCKOPT_SO_BINDADDR:
@@ -1298,10 +1257,10 @@ _javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val)
}
/* Check to see if above operations succeeded */
- if (result != TARGET_NATIVE_OK)
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, SOCKET_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return;
}
#else /* not WITHOUT_NETWORK */
@@ -1319,8 +1278,9 @@ _javanet_get_option (JNIEnv * env, jobject this, jint option_id)
#ifndef WITHOUT_NETWORK
int fd;
int flag, optval;
- int address;
+ cpnet_address *address;
int result;
+ jobject obj;
/* Get the real file descriptor */
fd = _javanet_get_int_field (env, this, "native_fd");
@@ -1336,12 +1296,11 @@ _javanet_get_option (JNIEnv * env, jobject this, jint 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)
+ result = cpnet_getSocketTCPNoDelay (env, fd, &optval);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, SOCKET_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return (0);
}
@@ -1355,17 +1314,17 @@ _javanet_get_option (JNIEnv * env, jobject this, jint option_id)
/* 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)
+ result = cpnet_getLinger (env, fd, &flag, &optval);
+
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, SOCKET_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return (0);
}
- if (optval)
- return (_javanet_create_integer (env, JNI_TRUE));
+ if (flag)
+ return (_javanet_create_integer (env, optval));
else
return (_javanet_create_boolean (env, JNI_FALSE));
@@ -1373,34 +1332,27 @@ _javanet_get_option (JNIEnv * env, jobject this, jint option_id)
/* 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)
+ result = cpnet_getSocketTimeout (env, fd, &optval);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, SOCKET_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
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);
+ result = cpnet_getSendBuf (env, fd, &optval);
else
- TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_SO_RCDBUF (fd, optval,
- result);
- if (result != TARGET_NATIVE_OK)
+ result = cpnet_getRecvBuf (env, fd, &optval);
+
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, SOCKET_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return (0);
}
@@ -1409,11 +1361,11 @@ _javanet_get_option (JNIEnv * env, jobject this, jint option_id)
/* 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)
+ result = cpnet_getTTL (env, fd, &optval);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, SOCKET_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return (0);
}
@@ -1422,61 +1374,64 @@ _javanet_get_option (JNIEnv * env, jobject this, jint option_id)
/* 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)
+ result = cpnet_getMulticastIF (env, fd, &address);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, SOCKET_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return (0);
}
- return (_javanet_create_inetaddress (env, address));
+ obj = _javanet_create_inetaddress (env, address);
+ cpnet_freeAddress (env, address);
+
+ return obj;
break;
case SOCKOPT_SO_BINDADDR:
- TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_BIND_ADDRESS (fd, address,
- result);
- if (result != TARGET_NATIVE_OK)
+ result = cpnet_getLocalAddr (env, fd, &address);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, SOCKET_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return (0);
}
- return (_javanet_create_inetaddress (env, address));
+ obj = _javanet_create_inetaddress (env, address);
+ cpnet_freeAddress (env, address);
+
+ return obj;
break;
case SOCKOPT_SO_REUSEADDR:
- TARGET_NATIVE_NETWORK_SOCKET_GET_OPTION_REUSE_ADDRESS (fd, optval,
- result);
- if (result != TARGET_NATIVE_OK)
+ result = cpnet_getReuseAddress (env, fd, &optval);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, SOCKET_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return (0);
}
if (optval)
- return (_javanet_create_boolean (env, JNI_TRUE));
+ return _javanet_create_boolean (env, JNI_TRUE);
else
- return (_javanet_create_boolean (env, JNI_FALSE));
+ 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)
+ result = cpnet_getKeepAlive (env, fd, &optval);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, SOCKET_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING ());
+ cpnative_getErrorString (result));
return (0);
}
if (optval)
- return (_javanet_create_boolean (env, JNI_TRUE));
+ return _javanet_create_boolean (env, JNI_TRUE);
else
- return (_javanet_create_boolean (env, JNI_FALSE));
+ return _javanet_create_boolean (env, JNI_FALSE);
break;
@@ -1493,6 +1448,7 @@ _javanet_get_option (JNIEnv * env, jobject this, jint option_id)
void
_javanet_shutdownInput (JNIEnv * env, jobject this)
{
+ int result;
int fd;
/* Get the real file descriptor. */
@@ -1505,10 +1461,11 @@ _javanet_shutdownInput (JNIEnv * env, jobject this)
}
/* Shutdown input stream of socket. */
- if (shutdown (fd, SHUT_RD) == -1)
+ result = cpnet_shutdown (env, fd, CPNET_SHUTDOWN_READ);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, SOCKET_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING());
+ cpnative_getErrorString (result));
return;
}
}
@@ -1517,6 +1474,7 @@ void
_javanet_shutdownOutput (JNIEnv * env, jobject this)
{
int fd;
+ int result;
/* Get the real file descriptor. */
fd = _javanet_get_int_field (env, this, "native_fd");
@@ -1528,10 +1486,11 @@ _javanet_shutdownOutput (JNIEnv * env, jobject this)
}
/* Shutdown output stream of socket. */
- if (shutdown (fd, SHUT_WR) == -1)
+ result = cpnet_shutdown (env, fd, CPNET_SHUTDOWN_WRITE);
+ if (result != CPNATIVE_OK)
{
JCL_ThrowException (env, SOCKET_EXCEPTION,
- TARGET_NATIVE_LAST_ERROR_STRING());
+ cpnative_getErrorString (result));
return;
}
}
diff --git a/libjava/classpath/native/jni/java-net/javanet.h b/libjava/classpath/native/jni/java-net/javanet.h
index 030d41282ba..96dba881b54 100644
--- a/libjava/classpath/native/jni/java-net/javanet.h
+++ b/libjava/classpath/native/jni/java-net/javanet.h
@@ -41,6 +41,7 @@ exception statement from your version. */
#include <jni.h>
#include "jcl.h"
+#include "cpnet.h"
/*************************************************************************/
@@ -54,6 +55,7 @@ exception statement from your version. */
#define CONNECT_EXCEPTION "java/net/ConnectException"
#define SOCKET_EXCEPTION "java/net/SocketException"
#define UNKNOWN_HOST_EXCEPTION "java/net/UnknownHostException"
+#define NULL_EXCEPTION "java/lang/NullPointerException"
/* Socket Option Identifiers - Don't change or binary compatibility with
the JDK will be broken! These also need to
@@ -78,15 +80,16 @@ exception statement from your version. */
*/
extern int _javanet_get_int_field(JNIEnv *, jobject, const char *);
-extern int _javanet_get_netaddr(JNIEnv *, jobject);
+extern cpnet_address *_javanet_get_ip_netaddr(JNIEnv *, jobject);
+extern jobject _javanet_create_inetaddress (JNIEnv *, cpnet_address *);
extern void _javanet_create(JNIEnv *, jobject, jboolean);
extern void _javanet_close(JNIEnv *, jobject, int);
extern void _javanet_connect(JNIEnv *, jobject, jobject, jint, jboolean);
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 int _javanet_recvfrom(JNIEnv *, jobject, jarray, int, int, cpnet_address **);
+extern void _javanet_sendto(JNIEnv *, jobject, jarray, int, int, cpnet_address *);
extern jobject _javanet_get_option(JNIEnv *, jobject, jint);
extern void _javanet_set_option(JNIEnv *, jobject, jint, jobject);
extern void _javanet_shutdownInput (JNIEnv *, jobject);
diff --git a/libjava/classpath/native/jni/java-net/local.c b/libjava/classpath/native/jni/java-net/local.c
index cdddd89efc3..c8ca91c2ab5 100644
--- a/libjava/classpath/native/jni/java-net/local.c
+++ b/libjava/classpath/native/jni/java-net/local.c
@@ -36,9 +36,7 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif /* HAVE_CONFIG_H */
#ifdef ENABLE_LOCAL_SOCKETS
OpenPOWER on IntegriCloud