Hi,

Here is the proposed default implementation for CPNET. It surely have bugs but for now it compiles.

ChangeLog:
2006-02-19  Guilhem Lavaux  <[EMAIL PROTECTED]>

        * configure.ac: Invoke GCC_ATTRIBUTE_UNUSED.

        * m4/gcc_attribute.m4: New file from ac_archive.

        * native/jni/java-net/javanet.c: Adapted to cpnet API
        modification.

        * native/jni/native-lib/cpnet.c: Implemented.

        * native/jni/native-lib/cpnet.h
        (cpnet_openSocketDatagram,
        cpnet_openSocketStream): These calls need an address family now.
        (cpnet_IPV4AddressToBytes,
        cpnet_bytesToIPV4Address): Convert the address to network order.

? build
? log
Index: configure.ac
===================================================================
RCS file: /cvsroot/classpath/classpath/configure.ac,v
retrieving revision 1.132.2.2
diff -u -r1.132.2.2 configure.ac
--- configure.ac        18 Feb 2006 18:33:27 -0000      1.132.2.2
+++ configure.ac        19 Feb 2006 17:06:06 -0000
@@ -235,6 +235,8 @@
 AC_PROG_CPP
 
 if test "x${COMPILE_JNI}" = xyes; then
+  GCC_ATTRIBUTE_UNUSED
+
   AC_HEADER_STDC
 
   dnl Checking sizeof void * is needed for fdlibm to work properly on ppc64, 
Index: m4/gcc_attribute.m4
===================================================================
RCS file: m4/gcc_attribute.m4
diff -N m4/gcc_attribute.m4
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ m4/gcc_attribute.m4 19 Feb 2006 17:06:07 -0000
@@ -0,0 +1,133 @@
+dnl 
CACHED_TRY_COMPILE(<description>,<cachevar>,<include>,<program>,<ifyes>,<ifno>)
+AC_DEFUN([CACHED_TRY_COMPILE],[
+ AC_MSG_CHECKING($1)
+ AC_CACHE_VAL($2,[
+  AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$3]], [[$4]])],[$2=yes],[$2=no])
+ ])
+ if test "x$$2" = xyes; then
+  true
+  $5
+ else
+  true
+  $6
+ fi
+])
+
+dnl 
GCC_ATTRIBUTE(<short-label>,<cachevar>,<func-params>,<attribute>,<HAVE>,<desc>,[<true-cmds>],[<false-cmds>])
+AC_DEFUN([GCC_ATTRIBUTE],[
+  CACHED_TRY_COMPILE(__attribute__(($1)),cv_c_gcc_attribute_$2,,
+   [extern int testfunction($3) __attribute__(($4))],
+   AC_MSG_RESULT(yes)
+   AC_DEFINE(HAVE_GNUC25_$5,,$6)
+   $7,
+   AC_MSG_RESULT(no)
+   $8)
+])
+
+
+AC_DEFUN([GCC_ATTRIBUTE_SUPPORTED],[
+ GCC_ATTRIBUTE([,,],supported,[int x],[,,],ATTRIB,[Define if function 
attributes a la GCC 2.5 and higher are available.])
+ AH_BOTTOM([/* GNU C attributes. */
+#ifndef FUNCATTR
+#ifdef HAVE_GNUC25_ATTRIB
+#define FUNCATTR(x) __attribute__(x)
+#else
+#define FUNCATTR(x)
+#endif
+#endif])
+
+])
+AC_DEFUN([GCC_ATTRIBUTE_CONST],[
+ AC_REQUIRE([GCC_ATTRIBUTE_SUPPORTED])
+ GCC_ATTRIBUTE(const,const,[int x],const,CONST,[Define if constant functions a 
la GCC 2.5 and higher are available.])
+ AH_BOTTOM([/* GNU C constant functions, or null. */
+#ifndef ATTRCONST
+#ifdef HAVE_GNUC25_CONST
+#define ATTRCONST const
+#else
+#define ATTRCONST
+#endif
+#endif
+#ifndef CONSTANT
+#define CONSTANT FUNCATTR((ATTRCONST))
+#endif])
+])
+AC_DEFUN([GCC_ATTRIBUTE_NORETURN],[
+ AC_REQUIRE([GCC_ATTRIBUTE_SUPPORTED])
+ GCC_ATTRIBUTE(noreturn,noreturn,[int x],noreturn,NORETURN,[Define if 
nonreturning functions a la GCC 2.5 and higher are available.])
+ AH_BOTTOM([/* GNU C nonreturning functions, or null. */
+#ifndef ATTRNORETURN
+#ifdef HAVE_GNUC25_NORETURN
+#define ATTRNORETURN noreturn
+#else /* ! HAVE_GNUC25_NORETURN */
+#define ATTRNORETURN
+#endif /* HAVE_GNUC25_NORETURN */
+#endif /* ATTRNORETURN */
+#ifndef NONRETURNING
+#define NONRETURNING FUNCATTR((ATTRNORETURN))
+#endif /* NONRETURNING */])
+])
+AC_DEFUN([GCC_ATTRIBUTE_UNUSED],[
+ AC_REQUIRE([GCC_ATTRIBUTE_SUPPORTED])
+ GCC_ATTRIBUTE(unused,unused,[int x],unused,UNUSED,[Define if unused variables 
la GCC 2.5 and higher are available.])
+ AH_BOTTOM([/* GNU C unused functions, or null. */
+#ifndef ATTRUNUSED
+#ifdef HAVE_GNUC25_UNUSED
+#define ATTRUNUSED unused
+#else
+#define ATTRUNUSED
+#endif
+#endif
+#ifndef UNUSED
+#define UNUSED FUNCATTR((ATTRUNUSED))
+#endif])
+])
+AC_DEFUN([GCC_ATTRIBUTE_FORMAT],[
+ AC_REQUIRE([GCC_ATTRIBUTE_SUPPORTED])
+ GCC_ATTRIBUTE(format...,format,[char *y, 
...],[format(printf,1,2)],PRINTFFORMAT,[Define if printf-format argument lists 
a la GCC are available.])
+ AH_BOTTOM([/* GNU C printf formats, or null. */
+#ifndef ATTRPRINTF
+#ifdef HAVE_GNUC25_PRINTFFORMAT
+#define ATTRPRINTF(si,tc) format(printf,si,tc)
+#else
+#define ATTRPRINTF(si,tc)
+#endif
+#endif
+#ifndef PRINTFFORMAT
+#define PRINTFFORMAT(si,tc) FUNCATTR((ATTRPRINTF(si,tc)))
+#endif
+
+#ifndef NONRETURNPRINTFFORMAT
+#define NONRETURNPRINTFFORMAT(si,tc) FUNCATTR((ATTRPRINTF(si,tc),ATTRNORETURN))
+#endif])
+])
+AC_DEFUN([GCC_ATTRIBUTE_ALWAYS_INLINE],[
+ AC_REQUIRE([GCC_ATTRIBUTE_SUPPORTED])
+ GCC_ATTRIBUTE(always_inline,always_inline,[int 
x],always_inline,ALWAYS_INLINE,[Define if unconditional inlining of functions a 
la GCC 3.1 and higher are available.])
+ AH_BOTTOM([/* GNU C constant functions, or null. */
+#ifndef ATTRALWAYS_INLINE
+#ifdef HAVE_GNUC25_ALWAYS_INLINE
+#define ATTRALWAYS_INLINE always_inline
+#else
+#define ATTRALWAYS_INLINE
+#endif
+#endif
+#ifndef ALWAYS_INLINE
+#define ALWAYS_INLINE FUNCATTR((ATTRALWAYS_INLINE))
+#endif])
+])
+AC_DEFUN([GCC_ATTRIBUTE_PACKED],[
+ AC_REQUIRE([GCC_ATTRIBUTE_SUPPORTED])
+ GCC_ATTRIBUTE(packed,packed,[int x],packed,PACKED,[Define if packing of 
struct members a la GCC 2.5 and higher is available.])
+ AH_BOTTOM([/* GNU C constant functions, or null. */
+#ifndef ATTRPACKED
+#ifdef HAVE_GNUC25_PACKED
+#define ATTRPACKED packed
+#else
+#define ATTRPACKED
+#endif
+#endif
+#ifndef PACKED
+#define PACKED FUNCATTR((ATTRPACKED))
+#endif])
+])
Index: native/jni/java-net/javanet.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/java-net/javanet.c,v
retrieving revision 1.32.2.6
diff -u -r1.32.2.6 javanet.c
--- native/jni/java-net/javanet.c       18 Feb 2006 18:59:54 -0000      1.32.2.6
+++ native/jni/java-net/javanet.c       19 Feb 2006 17:06:07 -0000
@@ -430,7 +430,7 @@
   if (stream)
     {
       /* create a stream socket */
-      result = cpnet_openSocketStream(env, &fd);
+      result = cpnet_openSocketStream(env, &fd, AF_INET);
       if (result != CPNATIVE_OK)
        {
          JCL_ThrowException (env, IO_EXCEPTION,
@@ -441,7 +441,7 @@
   else
     {
       /* create a datagram socket, set broadcast option */
-      result = cpnet_openSocketDatagram (env, &fd);
+      result = cpnet_openSocketDatagram (env, &fd, AF_INET);
       if (result != CPNATIVE_OK)
        {
          JCL_ThrowException (env, IO_EXCEPTION,
@@ -1376,7 +1376,7 @@
       break;
 
     case SOCKOPT_SO_BINDADDR:
-      result = cpnet_getBindAddress (env, fd, &address);
+      result = cpnet_getLocalAddr (env, fd, &address);
       if (result != CPNATIVE_OK)
        {
          JCL_ThrowException (env, SOCKET_EXCEPTION,
Index: native/jni/native-lib/cpnet.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/native-lib/Attic/cpnet.c,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 cpnet.c
--- native/jni/native-lib/cpnet.c       28 Jan 2006 15:48:58 -0000      1.1.2.1
+++ native/jni/native-lib/cpnet.c       19 Feb 2006 17:06:07 -0000
@@ -0,0 +1,658 @@
+/* cpnet.c -
+   Copyright (C) 2003, 2004, 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. */
+
+#include "config.h"
+#include <jni.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+
+#include "cpnet.h"
+
+jint cpnet_openSocketStream(JNIEnv *env UNUSED, jint *fd, jint family)
+{
+  *fd = socket(family, SOCK_STREAM, 0);
+  if (*fd == -1)
+    return errno;
+
+  fcntl(*fd, F_SETFD, FD_CLOEXEC);
+  return 0;
+}
+
+jint cpnet_openSocketDatagram(JNIEnv *env UNUSED, jint *fd, jint family)
+{
+  *fd = socket(family, SOCK_DGRAM, 0);
+  if (*fd == -1)
+    return errno;
+
+  fcntl(*fd, F_SETFD, FD_CLOEXEC);
+  return 0;
+}
+
+jint cpnet_shutdown (JNIEnv *env UNUSED, jint fd, jbyte flag)
+{
+  int ret;
+  int shut_flag = 0;
+
+  if (flag == CPNET_SHUTDOWN_READ)
+    shut_flag = SHUT_RD;
+  else if (flag == CPNET_SHUTDOWN_WRITE)
+    shut_flag = SHUT_WR;
+
+  ret = shutdown (fd, shut_flag);
+  if (ret != 0)
+    return errno;
+  return 0;
+}
+
+jint cpnet_close(JNIEnv *env UNUSED, jint fd)
+{
+  if (close (fd) != 0)
+    return errno;
+  return 0;
+}
+
+jint cpnet_listen(JNIEnv *env UNUSED, jint fd, jint queuelen)
+{
+  if (listen (fd, queuelen) != 0)
+    return errno;
+  return 0;
+}
+
+jint cpnet_accept(JNIEnv *env UNUSED, jint fd, jint *newfd)
+{
+  *newfd = accept(fd, NULL, 0);
+  if (*newfd != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_bind(JNIEnv *env UNUSED, jint fd, cpnet_address *addr)
+{
+  int ret;
+
+  ret = bind(fd, (struct sockaddr *)addr->data, addr->len);
+  if (ret != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_connect(JNIEnv *env UNUSED, jint fd, cpnet_address *addr)
+{
+  int ret;
+
+  ret = connect(fd, (struct sockaddr *)addr->data, addr->len);
+  if (ret != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_getLocalAddr(JNIEnv *env, jint fd, cpnet_address **addr)
+{
+  socklen_t slen = 1024;
+  int ret;
+
+  *addr = JCL_malloc(env, slen);
+
+  slen -= sizeof(jint);
+  ret = getsockname(fd, (struct sockaddr *)(*addr)->data, &slen );
+  if (ret != 0)
+    {
+      int err = errno;
+      JCL_free(env, *addr);
+      return err;
+    }
+
+  (*addr)->len = slen;
+  
+  return 0;
+}
+
+jint cpnet_getRemoteAddr(JNIEnv *env, jint fd, cpnet_address **addr)
+{
+  socklen_t slen = 1024;
+  int ret;
+
+  *addr = JCL_malloc(env, slen);
+
+  slen -= sizeof(jint);
+  ret = getpeername(fd, (struct sockaddr *)(*addr)->data, &slen );
+  if (ret != 0)
+    {
+      int err = errno;
+      JCL_free(env, *addr);
+      return err;
+    }
+
+  (*addr)->len = slen;
+  
+  return 0;
+}
+
+jint cpnet_setBroadcast(JNIEnv *env UNUSED, jint fd, jint flag)
+{
+  int ret;
+
+  ret = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag));
+  if (ret != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_send (JNIEnv *env UNUSED, jint fd, jbyte *data, jint len, jint 
*bytes_sent)
+{
+  ssize_t ret;
+
+  ret = send(fd, data, len, MSG_NOSIGNAL);
+  if (ret < 0)
+    return errno;
+
+  *bytes_sent = ret;
+
+  return 0;
+}
+
+jint cpnet_sendTo (JNIEnv *env UNUSED, jint fd, jbyte *data, jint len, 
cpnet_address *addr, jint *bytes_sent)
+{
+  ssize_t ret;
+
+  ret = sendto(fd, data, len, MSG_NOSIGNAL, (struct sockaddr *)addr->data, 
addr->len);
+  if (ret < 0)
+    return errno;
+
+  *bytes_sent = ret;
+  return 0;
+}
+
+jint cpnet_recv (JNIEnv *env UNUSED, jint fd, jbyte *data, jint len, jint 
*bytes_recv)
+{
+  ssize_t ret;
+
+  ret = recv(fd, data, len, 0);
+  if (ret < 0)
+    return errno;
+
+  *bytes_recv = ret;
+
+  return 0;
+}
+
+jint cpnet_recvFrom (JNIEnv *env, jint fd, jbyte *data, jint len, 
cpnet_address **addr, jint *bytes_recv)
+{
+  socklen_t slen = 1024;
+  ssize_t ret;
+
+  *addr = JCL_malloc(env, slen);
+
+  slen -= sizeof(jint);
+  ret = recvfrom(fd, data, len, 0, (struct sockaddr *) (*addr)->data, &slen);
+  if (ret < 0)
+    {
+      int err = errno;
+      JCL_free(env, *addr);
+      return err;
+    }
+
+  (*addr)->len = slen;
+  *bytes_recv = len;
+
+  return 0;
+}
+
+jint cpnet_setSocketTCPNoDelay (JNIEnv *env UNUSED, jint fd, jint nodelay)
+{
+  socklen_t len = sizeof(jint);
+  int ret;
+
+  ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, len);
+  if (ret < 0)
+    return errno;
+
+  return 0; 
+}
+
+jint cpnet_getSocketTCPNoDelay (JNIEnv *env UNUSED, jint fd, jint *nodelay)
+{
+  socklen_t len = sizeof(jint);
+  int ret;
+
+  ret = getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, nodelay, &len);
+  if (ret < 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_setLinger (JNIEnv *env UNUSED, jint fd, jint flag, jint value)
+{
+  socklen_t len = sizeof(struct linger);
+  int ret;
+  struct linger __linger;
+
+  if (flag)
+    {
+      __linger.l_onoff = 0;
+    }
+  else
+    {
+      __linger.l_linger = value;
+      __linger.l_onoff = 1;
+    }
+
+  ret = setsockopt(fd, SOL_SOCKET, SO_LINGER, &__linger, len);
+  if (ret < 0)
+    return errno;
+
+  return 0; 
+}
+
+jint cpnet_getLinger (JNIEnv *env UNUSED, jint fd, jint *flag, jint *value)
+{
+  socklen_t slen = sizeof(struct linger);
+  struct linger __linger;
+  int ret;
+
+  ret = getsockopt(fd, SOL_SOCKET, SO_LINGER, &__linger, &slen);
+  if (ret != 0)
+    return errno;
+
+  *flag = __linger.l_onoff;
+  *value = __linger.l_linger;
+
+  return ret;
+}
+
+jint cpnet_setSocketTimeout (JNIEnv *env UNUSED, jint fd UNUSED, jint value 
UNUSED)
+{
+#if 0
+  /* This is not really the right default implementation. This will have to
+   * be changed. Most OSes do not completely/rightfully support SO_TIMEOUT.
+   */
+  struct timeval tval;
+  int ret;
+
+  tval.tv_sec = value / 1000;
+  tval.tv_usec = (value % 1000) * 1000;
+  ret = setsockopt (fd, SOL_SOCKET, SO_TIMEOUT, &tval, sizeof(tval));
+  if (ret != 0)
+    return errno;
+
+  return 0;
+#else
+  return ENOSYS;
+#endif
+}
+
+jint cpnet_getSocketTimeout (JNIEnv *env UNUSED, jint fd UNUSED, jint *value 
UNUSED)
+{
+#if 0
+  /* This is not really the right default implementation. This will have to
+   * be changed. Most OSes do not completely/rightfully support SO_TIMEOUT.
+   */
+  struct timeval tval;
+  int ret;
+
+  ret = getsockopt (fd, SOL_SOCKET, SO_TIMEOUT, &tval, sizeof(tval));
+  if (ret != 0)
+    return errno;
+
+  *value = (tval.tv_sec * 1000) + (tval.tv_usec / 1000);
+
+  return 0;
+#else
+  return ENOSYS;
+#endif
+}
+
+jint cpnet_setSendBuf (JNIEnv *env UNUSED, jint fd, jint value)
+{
+  int ret;
+
+  ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value));
+  if (ret != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_getSendBuf (JNIEnv *env UNUSED, jint fd, jint *value)
+{
+  int ret;
+  socklen_t slen = sizeof(*value);
+
+  ret = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, value, &slen);
+  if (ret != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_setRecvBuf (JNIEnv *env UNUSED, jint fd, jint value)
+{
+  int ret;
+
+  ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value));
+  if (ret != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_getRecvBuf (JNIEnv *env UNUSED, jint fd, jint *value)
+{
+  int ret;
+  socklen_t slen = sizeof(*value);
+
+  ret = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, value, &slen);
+  if (ret != 0)
+    return errno;
+  
+  return 0;
+}
+
+jint cpnet_setTTL (JNIEnv *env UNUSED, jint fd, jint value)
+{ 
+  int ret;
+
+  ret = setsockopt(fd, IPPROTO_IP, IP_TTL, &value, sizeof(value));
+  if (ret != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_getTTL (JNIEnv *env UNUSED, jint fd, jint *value)
+{
+  int ret;
+  socklen_t slen = sizeof(*value);
+
+  ret = getsockopt(fd, IPPROTO_IP, IP_TTL, value, &slen);
+  if (ret != 0)
+    return errno;
+  
+  return 0;
+}
+
+jint cpnet_setMulticastIF (JNIEnv *env UNUSED, jint fd, cpnet_address *addr)
+{
+  int ret;
+
+  ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (struct sockaddr 
*)addr->data, addr->len);
+  if (ret != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_getMulticastIF (JNIEnv *env, jint fd, cpnet_address **addr)
+{
+  socklen_t slen = 1024;
+  int ret;
+
+  *addr = JCL_malloc(env, slen);
+
+  slen -= sizeof(jint);
+  ret = getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (struct sockaddr 
*)(*addr)->data, &slen);
+  (*addr)->len = slen;
+
+  if (ret != 0)
+    return errno;
+  
+  return 0;
+}
+
+jint cpnet_setReuseAddress (JNIEnv *env UNUSED, jint fd, jint reuse)
+{
+  int ret;
+
+  ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
+  if (ret != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_getReuseAddress (JNIEnv *env UNUSED, jint fd, jint *reuse)
+{
+  int ret;
+  socklen_t slen = sizeof(*reuse);
+
+  ret = getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, reuse, &slen);
+  if (ret != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_setKeepAlive (JNIEnv *env UNUSED, jint fd, jint keep)
+{
+  int ret;
+
+  ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keep, sizeof(keep));
+  if (ret != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_getKeepAlive (JNIEnv *env UNUSED, jint fd, jint *keep)
+{
+  int ret;
+  socklen_t slen = sizeof(*keep);
+
+  ret = getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, keep, &slen);
+  if (ret != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_addMembership (JNIEnv *env UNUSED, jint fd, cpnet_address *addr)
+{
+  struct ip_mreq req;
+  int ret;
+  
+  memset(&req, 0, sizeof(req));
+  req.imr_multiaddr = ((struct sockaddr_in *)addr->data)->sin_addr;
+  req.imr_interface.s_addr = INADDR_ANY;
+  ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &req, sizeof(req));
+  if (ret != 0)
+    return errno;
+  
+  return 0;
+}
+
+jint cpnet_dropMembership (JNIEnv *env UNUSED, jint fd, cpnet_address *addr)
+{
+  struct ip_mreq req;
+  int ret;
+  
+  memset(&req, 0, sizeof(req));
+  req.imr_multiaddr = ((struct sockaddr_in *)addr->data)->sin_addr;
+  req.imr_interface.s_addr = INADDR_ANY;
+  ret = setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &req, sizeof(req));
+  if (ret != 0)
+    return errno;
+  
+  return 0;
+}
+
+jint cpnet_getAvailableBytes (JNIEnv *env UNUSED, jint fd, jint 
*availableBytes)
+{
+  int ret;
+
+  ret = ioctl(fd, FIONREAD, availableBytes);
+  if (ret != 0)
+    return errno;
+
+  return 0;
+}
+
+jint cpnet_getHostname (JNIEnv *env UNUSED, char *hostname, jint hostname_len)
+{
+  int ret;
+
+  ret = gethostname(hostname, hostname_len);
+  if (ret != 0)
+    return errno;
+
+  hostname[hostname_len-1] = 0;
+  return 0;
+}
+
+jint cpnet_getHostByName (JNIEnv *env, const char *hostname, cpnet_address 
***addresses, jint *addresses_count)
+{
+  struct hostent hret;
+  struct hostent *result;
+  jint buflen = 1024;
+  int herr;
+  int ret;
+  int counter = 0;
+  cpnet_address **addr_arr;
+  int i;
+  char *buf;
+
+  do
+    {
+      buf = (char *)JCL_malloc(env, buflen);
+      ret = gethostbyname_r (hostname, &hret, buf, buflen, &result, &herr);
+      if (ret != 0)
+       {
+         if (herr == ERANGE)
+           {
+             buflen *= 2;
+             JCL_free(env, buf);
+             continue;
+           }
+         JCL_free(env, buf);     
+
+         return herr;
+       }
+
+      break;
+    }
+  while (1);
+  
+  while (hret.h_addr_list[counter] != NULL)
+    counter++;
+
+  *addresses_count = counter;
+  addr_arr = *addresses = JCL_malloc(env, sizeof(cpnet_address *) * counter);
+  switch (hret.h_addrtype)
+    {
+    case AF_INET:
+      for (i = 0; i < counter; i++)
+       {
+         addr_arr[i] = cpnet_newIPV4Address(env);
+         cpnet_bytesToIPV4Address(addr_arr[i], (jbyte 
*)hret.h_addr_list[counter]);
+       }
+      break;
+    case AF_INET6:
+      for (i = 0; i < counter; i++)
+       {
+         addr_arr[i] = cpnet_newIPV6Address(env);
+         cpnet_bytesToIPV6Address(addr_arr[i], (jbyte 
*)hret.h_addr_list[counter]);
+       }
+      break;
+    default:
+      *addresses_count = 0;
+      JCL_free(env, addr_arr);
+      break;
+    }
+
+  JCL_free(env, buf);
+
+  return 0;
+}
+
+jint cpnet_getHostByAddr (JNIEnv *env UNUSED, cpnet_address *addr, char 
*hostname, jint hostname_len)
+{
+  union 
+  {
+    struct sockaddr_in *addr_v4;
+    struct sockaddr_in6 *addr_v6;
+    char *data;
+  } haddr;
+  void *raw_addr;
+  int addr_type;
+  struct hostent *ret;
+  int addr_len;
+
+  haddr.data = addr->data;
+  
+  if (haddr.addr_v4->sin_family == AF_INET)
+    {
+      raw_addr = &haddr.addr_v4->sin_addr;
+      addr_len = sizeof(haddr.addr_v4->sin_addr);
+      addr_type = AF_INET;
+    }
+  else if (haddr.addr_v6->sin6_family == AF_INET6)
+    {
+      raw_addr = &haddr.addr_v6->sin6_addr;
+      addr_type = AF_INET6;
+      addr_len = sizeof(haddr.addr_v6->sin6_addr);
+    }
+  else
+    return EINVAL;
+
+  /* Here we do not have any thread safe call. VM implementors will have to
+   * do a big lock. Or it should be put on the Classpath VM interface.
+   */
+  ret = gethostbyaddr(raw_addr, addr_len, addr_type);
+  if (ret == NULL)
+    {
+      /* The trouble here is how to distinguish the two cases ? */
+      if (h_errno != 0)
+       return h_errno;
+      else
+       return errno;
+
+    }
+  strncpy(hostname, ret->h_name, hostname_len);
+
+  return 0;
+}
Index: native/jni/native-lib/cpnet.h
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/native-lib/Attic/cpnet.h,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 cpnet.h
--- native/jni/native-lib/cpnet.h       18 Feb 2006 18:15:55 -0000      1.1.2.4
+++ native/jni/native-lib/cpnet.h       19 Feb 2006 17:06:07 -0000
@@ -40,6 +40,7 @@
 
 #include <jni.h>
 #include <jcl.h>
+#include <string.h>
 
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -53,8 +54,8 @@
 #define CPNET_SHUTDOWN_READ 1
 #define CPNET_SHUTDOWN_WRITE 2
 
-JNIEXPORT jint cpnet_openSocketStream(JNIEnv *env, jint *fd);
-JNIEXPORT jint cpnet_openSocketDatagram(JNIEnv *env, jint *fd);
+JNIEXPORT jint cpnet_openSocketStream(JNIEnv *env, jint *fd, jint family);
+JNIEXPORT jint cpnet_openSocketDatagram(JNIEnv *env, jint *fd, jint family);
 JNIEXPORT jint cpnet_shutdown (JNIEnv *env, jint fd, jbyte flag);
 JNIEXPORT jint cpnet_close(JNIEnv *env, jint fd);
 JNIEXPORT jint cpnet_listen(JNIEnv *env, jint fd, jint queuelen);
@@ -175,7 +176,7 @@
 static inline void cpnet_IPV4AddressToBytes(cpnet_address *netaddr, jbyte 
*octets)
 {
   struct sockaddr_in *ipaddr = (struct sockaddr_in *)&(netaddr->data[0]);
-  jint sysaddr = ipaddr->sin_addr.s_addr;
+  jint sysaddr = ntohl(ipaddr->sin_addr.s_addr);
 
   octets[0] = (sysaddr >> 24) & 0xff;
   octets[1] = (sysaddr >> 16) & 0xff;
@@ -193,7 +194,7 @@
   sysaddr |= ((jint)octets[2]) << 8;
   sysaddr |= ((jint)octets[3]);
 
-  ipaddr->sin_addr.s_addr = sysaddr;
+  ipaddr->sin_addr.s_addr = htonl(sysaddr);
 }
 
 static inline void cpnet_IPV6AddressToBytes(cpnet_address *netaddr, jbyte 
*octets)

Reply via email to