This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: Moving native code in java.net into architecture dependant files


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi list,


Here is a patch which moves the native code of java.net into 
architecture dependant files for better/easier maintaining, as 
requested by several people.

For the "posix" target the files are slightly edit versions of the 
originals. Only the #ifdefs for "win32" are removed.

For the "win32" target the files are same as before. Out Windows 
specialists should take care of them. I dont know enough about it.

For the "ecos" target (do we really need it ?) all methods are just 
there. They are mostly throwing exceptions indicating they are 
unimplemented. Some are just returning default values.

Question: Is it useful to point to "ecos" for the native java.net code 
when DISABLE_JAVA_NET is defined ? This would make the code in the 
"posix" target a little bit clearer. Any ideas for this ?

The attached patch doesnt remove the old files but they will be remove 
when committing.


Michael
- -- 
Homepage: http://www.worldforge.org/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQE+cZXFWSOgCCdjSDsRAvaGAJwP+mmhjQMJTML/JqwpRvGpv3vHjgCgh1kQ
LJflf3BdTW7522Km+jerC7U=
=oYNA
-----END PGP SIGNATURE-----
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/libjava/ChangeLog,v
retrieving revision 1.1774
diff -u -r1.1774 ChangeLog
--- ChangeLog	11 Mar 2003 10:30:50 -0000	1.1774
+++ ChangeLog	14 Mar 2003 08:30:39 -0000
@@ -1,3 +1,20 @@
+2003-03-14  Michael Koch  <konqueror at gmx dot de>
+
+	* configure.in: Create links to architecture dependent files.
+	* configure: Regenerated.
+	* java/net/natInetAddressEcos.cc,
+	java/net/natInetAddressPosix.cc,
+	java/net/natInetAddressWin32.cc,
+	java/net/natNetworkInterfaceEcos.cc,
+	java/net/natNetworkInterfacePosix.cc,
+	java/net/natNetworkInterfaceWin32.cc,
+	java/net/natPlainDatagramSocketImplEcos.cc,
+	java/net/natPlainDatagramSocketImplPosix.cc,
+	java/net/natPlainDatagramSocketImplWin32.cc,
+	java/net/natPlainSocketImplEcos.cc,
+	java/net/natPlainSocketImplPosix.cc,
+	java/net/natPlainSocketImplWin32.cc: New files.
+
 2003-03-11  Michael Koch  <konqueror at gmx dot de>
 
 	* gnu/java/nio/ByteBufferImpl.java
Index: configure.in
===================================================================
RCS file: /cvs/gcc/gcc/libjava/configure.in,v
retrieving revision 1.152
diff -u -r1.152 configure.in
--- configure.in	2 Mar 2003 13:46:06 -0000	1.152
+++ configure.in	14 Mar 2003 08:30:40 -0000
@@ -269,6 +269,14 @@
 AC_LINK_FILES(java/lang/${PLATFORM}Process.java, java/lang/ConcreteProcess.java)
 AC_LINK_FILES(java/lang/nat${PLATFORM}Process.cc, java/lang/natConcreteProcess.cc)
 
+dnl Likewise for natInetAddress.cc, natNetworkInterface.cc, natPlainSocketImpl.cc
+dnl and natPlainDatagramSocketImpl.cc
+test -d java/net || mkdir java/net
+AC_LINK_FILES(java/net/natInetAddress${PLATFORM}.cc, java/lang/natInetAddress.cc)
+AC_LINK_FILES(java/net/natNetworkInterface${PLATFORM}.cc, java/lang/natNetworkInterface.cc)
+AC_LINK_FILES(java/net/natPlainSocketImpl${PLATFORM}.cc, java/lang/natPlainSocketImpl.cc)
+AC_LINK_FILES(java/net/natPlainDatagramSocketImpl${PLATFORM}.cc, java/lang/natPlainDatagramSocketImpl.cc)
+
 case "${host}" in
     *mingw*)
       SYSTEMSPEC="-lgdi32 -lwsock32 -lws2_32"
Index: configure
===================================================================
RCS file: /cvs/gcc/gcc/libjava/configure,v
retrieving revision 1.170
diff -u -r1.170 configure
--- configure	2 Mar 2003 13:46:05 -0000	1.170
+++ configure	14 Mar 2003 08:30:44 -0000
@@ -3206,6 +3206,12 @@
 
 
 
+test -d java/net || mkdir java/net
+
+
+
+
+
 case "${host}" in
     *mingw*)
       SYSTEMSPEC="-lgdi32 -lwsock32 -lws2_32"
@@ -9121,8 +9127,8 @@
 EOF
 
 cat >> $CONFIG_STATUS <<EOF
-ac_sources="include/$PLATFORMH java/io/natFile${FILE-${PLATFORM}}.cc java/io/natFileDescriptor${FILE-${PLATFORM}}.cc java/lang/${PLATFORM}Process.java java/lang/nat${PLATFORM}Process.cc include/$GCHDR include/$THREADH sysdep/$sysdeps_dir/locks.h $SIGNAL_HANDLER"
-ac_dests="include/platform.h java/io/natFile.cc java/io/natFileDescriptor.cc java/lang/ConcreteProcess.java java/lang/natConcreteProcess.cc include/java-gc.h include/java-threads.h sysdep/locks.h include/java-signal.h"
+ac_sources="include/$PLATFORMH java/io/natFile${FILE-${PLATFORM}}.cc java/io/natFileDescriptor${FILE-${PLATFORM}}.cc java/lang/${PLATFORM}Process.java java/lang/nat${PLATFORM}Process.cc java/net/natInetAddress${PLATFORM}.cc java/net/natNetworkInterface${PLATFORM}.cc java/net/natPlainSocketImpl${PLATFORM}.cc java/net/natPlainDatagramSocketImpl${PLATFORM}.cc include/$GCHDR include/$THREADH sysdep/$sysdeps_dir/locks.h $SIGNAL_HANDLER"
+ac_dests="include/platform.h java/io/natFile.cc java/io/natFileDescriptor.cc java/lang/ConcreteProcess.java java/lang/natConcreteProcess.cc java/lang/natInetAddress.cc java/lang/natNetworkInterface.cc java/lang/natPlainSocketImpl.cc java/lang/natPlainDatagramSocketImpl.cc include/java-gc.h include/java-threads.h sysdep/locks.h include/java-signal.h"
 EOF
 
 cat >> $CONFIG_STATUS <<\EOF
Index: java/net/natInetAddressEcos.cc
===================================================================
RCS file: java/net/natInetAddressEcos.cc
diff -N java/net/natInetAddressEcos.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/net/natInetAddressEcos.cc	14 Mar 2003 08:30:44 -0000
@@ -0,0 +1,35 @@
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#include <java/net/InetAddress.h>
+
+jbyteArray
+java::net::InetAddress::aton (jstring)
+{
+  return NULL;
+}
+
+jint
+java::net::InetAddress::getFamily (jbyteArray bytes)
+{
+  return 0;
+}
+
+JArray<java::net::InetAddress*> *
+java::net::InetAddress::lookup (jstring, java::net::InetAddress *, jboolean)
+{
+  return NULL;
+}
+
+jstring
+java::net::InetAddress::getLocalHostname ()
+{
+  return NULL;
+}
Index: java/net/natInetAddressPosix.cc
===================================================================
RCS file: java/net/natInetAddressPosix.cc
diff -N java/net/natInetAddressPosix.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/net/natInetAddressPosix.cc	14 Mar 2003 08:30:44 -0000
@@ -0,0 +1,341 @@
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/net/InetAddress.h>
+#include <java/net/UnknownHostException.h>
+#include <java/lang/SecurityException.h>
+
+#if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME)
+#include <sys/utsname.h>
+#endif
+
+#ifndef HAVE_GETHOSTNAME_DECL
+extern "C" int gethostname (char *name, int namelen);
+#endif
+
+#ifdef DISABLE_JAVA_NET
+
+jbyteArray
+java::net::InetAddress::aton (jstring)
+{
+  return NULL;
+}
+
+jint
+java::net::InetAddress::getFamily (jbyteArray bytes)
+{
+  return 0;
+}
+
+JArray<java::net::InetAddress*> *
+java::net::InetAddress::lookup (jstring, java::net::InetAddress *, jboolean)
+{
+  return NULL;
+}
+
+jstring
+java::net::InetAddress::getLocalHostname ()
+{
+  return NULL;
+}
+
+#else /* DISABLE_JAVA_NET */
+
+jbyteArray
+java::net::InetAddress::aton (jstring host)
+{
+  char *hostname;
+  char buf[100];
+  int len = JvGetStringUTFLength(host);
+  if (len < 100)
+    hostname = buf;
+  else
+    hostname = (char*) _Jv_AllocBytes (len+1);
+  JvGetStringUTFRegion (host, 0, host->length(), hostname);
+  buf[len] = '\0';
+  char* bytes = NULL;
+  int blen = 0;
+#ifdef HAVE_INET_ATON
+  struct in_addr laddr;
+  if (inet_aton (hostname, &laddr))
+    {
+      bytes = (char*) &laddr;
+      blen = 4;
+    }
+#elif defined(HAVE_INET_ADDR)
+#if ! HAVE_IN_ADDR_T
+  typedef jint in_addr_t;
+#endif
+  in_addr_t laddr = inet_addr (hostname);
+  if (laddr != (in_addr_t)(-1))
+    {
+      bytes = (char*) &laddr;
+      blen = 4;
+    }
+#endif
+#if defined (HAVE_INET_PTON) && defined (HAVE_INET6)
+  char inet6_addr[16];
+  if (len != 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0)
+    {
+      bytes = inet6_addr;
+      blen = 16;
+    }
+#endif
+  if (blen == 0)
+    return NULL;
+  jbyteArray result = JvNewByteArray (blen);
+  memcpy (elements (result), bytes, blen);
+  return result;
+}
+
+jint
+java::net::InetAddress::getFamily (jbyteArray bytes)
+{
+  int len = bytes->length;
+  if (len == 4)
+    return AF_INET;
+#ifdef HAVE_INET6
+  else if (len == 16)
+    return AF_INET6;
+#endif /* HAVE_INET6 */
+  else
+    JvFail ("unrecognized size");
+}
+
+
+JArray<java::net::InetAddress*> *
+java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
+				jboolean all)
+{
+  struct hostent *hptr = NULL;
+#if defined (HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR_R)
+  struct hostent hent_r;
+#if HAVE_STRUCT_HOSTENT_DATA
+  struct hostent_data fixed_buffer, *buffer_r = &fixed_buffer;
+#else
+#if defined (__GLIBC__) 
+  // FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and
+  // ERANGE to errno if the buffer size is too small, rather than what is 
+  // expected here. We work around this by setting a bigger buffer size and 
+  // hoping that it is big enough.
+  char fixed_buffer[1024];
+#else
+  char fixed_buffer[200];
+#endif
+  char *buffer_r = fixed_buffer;
+  int size_r = sizeof (fixed_buffer);
+#endif
+#endif
+
+  if (host != NULL)
+    {
+      char *hostname;
+      char buf[100];
+      int len = JvGetStringUTFLength(host);
+      if (len < 100)
+	hostname = buf;
+      else
+	hostname = (char*) _Jv_AllocBytes (len+1);
+      JvGetStringUTFRegion (host, 0, host->length(), hostname);
+      buf[len] = '\0';
+#ifdef HAVE_GETHOSTBYNAME_R
+      while (true)
+	{
+	  int ok;
+#if HAVE_STRUCT_HOSTENT_DATA
+	  ok = ! gethostbyname_r (hostname, &hent_r, buffer_r);
+#else
+	  int herr = 0;
+#ifdef GETHOSTBYNAME_R_RETURNS_INT
+	  ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r,
+				  &hptr, &herr);
+#else
+	  hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr);
+	  ok = hptr != NULL;
+#endif /* GETHOSTNAME_R_RETURNS_INT */
+	  if (! ok && herr == ERANGE)
+	    {
+	      size_r *= 2;
+	      buffer_r = (char *) _Jv_AllocBytes (size_r);
+	    }
+	  else
+#endif /* HAVE_STRUCT_HOSTENT_DATA */
+	    break;
+	}
+#else
+      // FIXME: this is insufficient if some other piece of code calls
+      // this gethostbyname.
+      JvSynchronize sync (java::net::InetAddress::localhostAddress);
+      hptr = gethostbyname (hostname);
+#endif /* HAVE_GETHOSTBYNAME_R */
+    }
+  else
+    {
+      jbyteArray bytes = iaddr->addr;
+      char *chars = (char*) elements (bytes);
+      int len = bytes->length;
+      int type;
+      char *val;
+      if (len == 4)
+	{
+	  val = chars;
+	  type = iaddr->family = AF_INET;
+	}
+#ifdef HAVE_INET6
+      else if (len == 16)
+	{
+	  val = (char *) &chars;
+	  type = iaddr->family = AF_INET6;
+	}
+#endif /* HAVE_INET6 */
+      else
+	JvFail ("unrecognized size");
+
+#ifdef HAVE_GETHOSTBYADDR_R
+      while (true)
+	{
+	  int ok;
+#if HAVE_STRUCT_HOSTENT_DATA
+	  ok = ! gethostbyaddr_r (val, len, type, &hent_r, buffer_r);
+#else
+	  int herr = 0;
+#ifdef GETHOSTBYADDR_R_RETURNS_INT
+	  ok = ! gethostbyaddr_r (val, len, type, &hent_r,
+				  buffer_r, size_r, &hptr, &herr);
+#else
+	  hptr = gethostbyaddr_r (val, len, type, &hent_r,
+				  buffer_r, size_r, &herr);
+	  ok = hptr != NULL;
+#endif /* GETHOSTBYADDR_R_RETURNS_INT */
+	  if (! ok && herr == ERANGE)
+	    {
+	      size_r *= 2;
+	      buffer_r = (char *) _Jv_AllocBytes (size_r);
+	    }
+	  else 
+#endif /* HAVE_STRUCT_HOSTENT_DATA */
+	    break;
+	}
+#else /* HAVE_GETHOSTBYADDR_R */
+      // FIXME: this is insufficient if some other piece of code calls
+      // this gethostbyaddr.
+      JvSynchronize sync (java::net::InetAddress::localhostAddress);
+      hptr = gethostbyaddr (val, len, type);
+#endif /* HAVE_GETHOSTBYADDR_R */
+    }
+  if (hptr != NULL)
+    {
+      if (!all)
+        host = JvNewStringUTF (hptr->h_name);
+      java::lang::SecurityException *ex = checkConnect (host);
+      if (ex != NULL)
+	{
+	  if (iaddr == NULL || iaddr->addr == NULL)
+	    throw ex;
+	  hptr = NULL;
+	}
+    }
+  if (hptr == NULL)
+    {
+      if (iaddr != NULL && iaddr->addr != NULL)
+	{
+	  iaddr->hostName = iaddr->getHostAddress();
+	  return NULL;
+	}
+      else
+	throw new java::net::UnknownHostException(host);
+    }
+  int count;
+  if (all)
+    {
+      char** ptr = hptr->h_addr_list;
+      count = 0;
+      while (*ptr++)  count++;
+    }
+  else
+    count = 1;
+  JArray<java::net::InetAddress*> *result;
+  java::net::InetAddress** iaddrs;
+  if (all)
+    {
+      result = java::net::InetAddress::allocArray (count);
+      iaddrs = elements (result);
+    }
+  else
+    {
+      result = NULL;
+      iaddrs = &iaddr;
+    }
+
+  for (int i = 0;  i < count;  i++)
+    {
+      if (iaddrs[i] == NULL)
+	iaddrs[i] = new java::net::InetAddress (NULL, NULL);
+      if (iaddrs[i]->hostName == NULL)
+        iaddrs[i]->hostName = host;
+      if (iaddrs[i]->addr == NULL)
+	{
+	  char *bytes = hptr->h_addr_list[i];
+	  iaddrs[i]->addr = JvNewByteArray (hptr->h_length);
+	  iaddrs[i]->family = getFamily (iaddrs[i]->addr);
+	  memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length);
+	}
+    }
+  return result;
+}
+
+jstring
+java::net::InetAddress::getLocalHostname ()
+{
+  char *chars;
+#ifdef HAVE_GETHOSTNAME
+  char buffer[MAXHOSTNAMELEN];
+  if (gethostname (buffer, MAXHOSTNAMELEN))
+    return NULL;
+  chars = buffer;
+#elif HAVE_UNAME
+  struct utsname stuff;
+  if (uname (&stuff) != 0)
+    return NULL;
+  chars = stuff.nodename;
+#else
+  return NULL;
+#endif
+  // It is admittedly non-optimal to convert the hostname to Unicode
+  // only to convert it back in getByName, but simplicity wins.  Note
+  // that unless there is a SecurityManager, we only get called once
+  // anyway, thanks to the InetAddress.localhost cache.
+  return JvNewStringUTF (chars);
+}
+
+#endif /* DISABLE_JAVA_NET */
Index: java/net/natInetAddressWin32.cc
===================================================================
RCS file: java/net/natInetAddressWin32.cc
diff -N java/net/natInetAddressWin32.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/net/natInetAddressWin32.cc	14 Mar 2003 08:30:44 -0000
@@ -0,0 +1,355 @@
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+
+#ifdef WIN32
+
+#include <windows.h>
+#include <winsock.h>
+#undef STRICT
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN	64
+#endif /* MAXHOSTNAMELEN */
+
+#else /* WIN32 */
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#endif /* WIN32 */
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/net/InetAddress.h>
+#include <java/net/UnknownHostException.h>
+#include <java/lang/SecurityException.h>
+
+#if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME)
+#include <sys/utsname.h>
+#endif
+
+#ifndef HAVE_GETHOSTNAME_DECL
+extern "C" int gethostname (char *name, int namelen);
+#endif
+
+#ifdef DISABLE_JAVA_NET
+
+jbyteArray
+java::net::InetAddress::aton (jstring)
+{
+  return NULL;
+}
+
+jint
+java::net::InetAddress::getFamily (jbyteArray bytes)
+{
+  return 0;
+}
+
+JArray<java::net::InetAddress*> *
+java::net::InetAddress::lookup (jstring, java::net::InetAddress *, jboolean)
+{
+  return NULL;
+}
+
+jstring
+java::net::InetAddress::getLocalHostname ()
+{
+  return NULL;
+}
+
+#else /* DISABLE_JAVA_NET */
+
+jbyteArray
+java::net::InetAddress::aton (jstring host)
+{
+  char *hostname;
+  char buf[100];
+  int len = JvGetStringUTFLength(host);
+  if (len < 100)
+    hostname = buf;
+  else
+    hostname = (char*) _Jv_AllocBytes (len+1);
+  JvGetStringUTFRegion (host, 0, host->length(), hostname);
+  buf[len] = '\0';
+  char* bytes = NULL;
+  int blen = 0;
+#ifdef HAVE_INET_ATON
+  struct in_addr laddr;
+  if (inet_aton (hostname, &laddr))
+    {
+      bytes = (char*) &laddr;
+      blen = 4;
+    }
+#elif defined(HAVE_INET_ADDR)
+#if ! HAVE_IN_ADDR_T
+  typedef jint in_addr_t;
+#endif
+  in_addr_t laddr = inet_addr (hostname);
+  if (laddr != (in_addr_t)(-1))
+    {
+      bytes = (char*) &laddr;
+      blen = 4;
+    }
+#endif
+#if defined (HAVE_INET_PTON) && defined (HAVE_INET6)
+  char inet6_addr[16];
+  if (len != 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0)
+    {
+      bytes = inet6_addr;
+      blen = 16;
+    }
+#endif
+  if (blen == 0)
+    return NULL;
+  jbyteArray result = JvNewByteArray (blen);
+  memcpy (elements (result), bytes, blen);
+  return result;
+}
+
+jint
+java::net::InetAddress::getFamily (jbyteArray bytes)
+{
+  int len = bytes->length;
+  if (len == 4)
+    return AF_INET;
+#ifdef HAVE_INET6
+  else if (len == 16)
+    return AF_INET6;
+#endif /* HAVE_INET6 */
+  else
+    JvFail ("unrecognized size");
+}
+
+
+JArray<java::net::InetAddress*> *
+java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
+				jboolean all)
+{
+  struct hostent *hptr = NULL;
+#if defined (HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR_R)
+  struct hostent hent_r;
+#if HAVE_STRUCT_HOSTENT_DATA
+  struct hostent_data fixed_buffer, *buffer_r = &fixed_buffer;
+#else
+#if defined (__GLIBC__) 
+  // FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and
+  // ERANGE to errno if the buffer size is too small, rather than what is 
+  // expected here. We work around this by setting a bigger buffer size and 
+  // hoping that it is big enough.
+  char fixed_buffer[1024];
+#else
+  char fixed_buffer[200];
+#endif
+  char *buffer_r = fixed_buffer;
+  int size_r = sizeof (fixed_buffer);
+#endif
+#endif
+
+  if (host != NULL)
+    {
+      char *hostname;
+      char buf[100];
+      int len = JvGetStringUTFLength(host);
+      if (len < 100)
+	hostname = buf;
+      else
+	hostname = (char*) _Jv_AllocBytes (len+1);
+      JvGetStringUTFRegion (host, 0, host->length(), hostname);
+      buf[len] = '\0';
+#ifdef HAVE_GETHOSTBYNAME_R
+      while (true)
+	{
+	  int ok;
+#if HAVE_STRUCT_HOSTENT_DATA
+	  ok = ! gethostbyname_r (hostname, &hent_r, buffer_r);
+#else
+	  int herr = 0;
+#ifdef GETHOSTBYNAME_R_RETURNS_INT
+	  ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r,
+				  &hptr, &herr);
+#else
+	  hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr);
+	  ok = hptr != NULL;
+#endif /* GETHOSTNAME_R_RETURNS_INT */
+	  if (! ok && herr == ERANGE)
+	    {
+	      size_r *= 2;
+	      buffer_r = (char *) _Jv_AllocBytes (size_r);
+	    }
+	  else
+#endif /* HAVE_STRUCT_HOSTENT_DATA */
+	    break;
+	}
+#else
+      // FIXME: this is insufficient if some other piece of code calls
+      // this gethostbyname.
+      JvSynchronize sync (java::net::InetAddress::localhostAddress);
+      hptr = gethostbyname (hostname);
+#endif /* HAVE_GETHOSTBYNAME_R */
+    }
+  else
+    {
+      jbyteArray bytes = iaddr->addr;
+      char *chars = (char*) elements (bytes);
+      int len = bytes->length;
+      int type;
+      char *val;
+      if (len == 4)
+	{
+	  val = chars;
+	  type = iaddr->family = AF_INET;
+	}
+#ifdef HAVE_INET6
+      else if (len == 16)
+	{
+	  val = (char *) &chars;
+	  type = iaddr->family = AF_INET6;
+	}
+#endif /* HAVE_INET6 */
+      else
+	JvFail ("unrecognized size");
+
+#ifdef HAVE_GETHOSTBYADDR_R
+      while (true)
+	{
+	  int ok;
+#if HAVE_STRUCT_HOSTENT_DATA
+	  ok = ! gethostbyaddr_r (val, len, type, &hent_r, buffer_r);
+#else
+	  int herr = 0;
+#ifdef GETHOSTBYADDR_R_RETURNS_INT
+	  ok = ! gethostbyaddr_r (val, len, type, &hent_r,
+				  buffer_r, size_r, &hptr, &herr);
+#else
+	  hptr = gethostbyaddr_r (val, len, type, &hent_r,
+				  buffer_r, size_r, &herr);
+	  ok = hptr != NULL;
+#endif /* GETHOSTBYADDR_R_RETURNS_INT */
+	  if (! ok && herr == ERANGE)
+	    {
+	      size_r *= 2;
+	      buffer_r = (char *) _Jv_AllocBytes (size_r);
+	    }
+	  else 
+#endif /* HAVE_STRUCT_HOSTENT_DATA */
+	    break;
+	}
+#else /* HAVE_GETHOSTBYADDR_R */
+      // FIXME: this is insufficient if some other piece of code calls
+      // this gethostbyaddr.
+      JvSynchronize sync (java::net::InetAddress::localhostAddress);
+      hptr = gethostbyaddr (val, len, type);
+#endif /* HAVE_GETHOSTBYADDR_R */
+    }
+  if (hptr != NULL)
+    {
+      if (!all)
+        host = JvNewStringUTF (hptr->h_name);
+      java::lang::SecurityException *ex = checkConnect (host);
+      if (ex != NULL)
+	{
+	  if (iaddr == NULL || iaddr->addr == NULL)
+	    throw ex;
+	  hptr = NULL;
+	}
+    }
+  if (hptr == NULL)
+    {
+      if (iaddr != NULL && iaddr->addr != NULL)
+	{
+	  iaddr->hostName = iaddr->getHostAddress();
+	  return NULL;
+	}
+      else
+	throw new java::net::UnknownHostException(host);
+    }
+  int count;
+  if (all)
+    {
+      char** ptr = hptr->h_addr_list;
+      count = 0;
+      while (*ptr++)  count++;
+    }
+  else
+    count = 1;
+  JArray<java::net::InetAddress*> *result;
+  java::net::InetAddress** iaddrs;
+  if (all)
+    {
+      result = java::net::InetAddress::allocArray (count);
+      iaddrs = elements (result);
+    }
+  else
+    {
+      result = NULL;
+      iaddrs = &iaddr;
+    }
+
+  for (int i = 0;  i < count;  i++)
+    {
+      if (iaddrs[i] == NULL)
+	iaddrs[i] = new java::net::InetAddress (NULL, NULL);
+      if (iaddrs[i]->hostName == NULL)
+        iaddrs[i]->hostName = host;
+      if (iaddrs[i]->addr == NULL)
+	{
+	  char *bytes = hptr->h_addr_list[i];
+	  iaddrs[i]->addr = JvNewByteArray (hptr->h_length);
+	  iaddrs[i]->family = getFamily (iaddrs[i]->addr);
+	  memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length);
+	}
+    }
+  return result;
+}
+
+jstring
+java::net::InetAddress::getLocalHostname ()
+{
+  char *chars;
+#ifdef HAVE_GETHOSTNAME
+  char buffer[MAXHOSTNAMELEN];
+  if (gethostname (buffer, MAXHOSTNAMELEN))
+    return NULL;
+  chars = buffer;
+#elif HAVE_UNAME
+  struct utsname stuff;
+  if (uname (&stuff) != 0)
+    return NULL;
+  chars = stuff.nodename;
+#else
+  return NULL;
+#endif
+  // It is admittedly non-optimal to convert the hostname to Unicode
+  // only to convert it back in getByName, but simplicity wins.  Note
+  // that unless there is a SecurityManager, we only get called once
+  // anyway, thanks to the InetAddress.localhost cache.
+  return JvNewStringUTF (chars);
+}
+
+#endif /* DISABLE_JAVA_NET */
Index: java/net/natNetworkInterfaceEcos.cc
===================================================================
RCS file: java/net/natNetworkInterfaceEcos.cc
diff -N java/net/natNetworkInterfaceEcos.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/net/natNetworkInterfaceEcos.cc	14 Mar 2003 08:30:44 -0000
@@ -0,0 +1,21 @@
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#include <java/net/NetworkInterface.h>
+#include <java/net/SocketException.h>
+#include <java/util/Vector.h>
+
+::java::util::Vector*
+java::net::NetworkInterface::getRealNetworkInterfaces ()
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("NetworkInterface.getrealNetworkInterfaces: unimplemented"));
+}
Index: java/net/natNetworkInterfacePosix.cc
===================================================================
RCS file: java/net/natNetworkInterfacePosix.cc
diff -N java/net/natNetworkInterfacePosix.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/net/natNetworkInterfacePosix.cc	14 Mar 2003 08:30:44 -0000
@@ -0,0 +1,128 @@
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#define BSD_COMP /* Get FIONREAD on Solaris2. */
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/net/NetworkInterface.h>
+#include <java/net/Inet4Address.h>
+#include <java/net/SocketException.h>
+#include <java/util/Vector.h>
+
+#ifdef DISABLE_JAVA_NET
+
+::java::util::Vector*
+java::net::NetworkInterface::getRealNetworkInterfaces ()
+{
+  ::java::util::Vector* ht = new ::java::util::Vector();
+  return ht;
+}
+
+#else /* DISABLE_JAVA_NET */
+
+::java::util::Vector*
+java::net::NetworkInterface::getRealNetworkInterfaces ()
+{
+  int fd;
+  int num_interfaces = 0;
+  struct ifconf if_data;
+  struct ifreq* if_record;
+  ::java::util::Vector* ht = new ::java::util::Vector ();
+
+  if_data.ifc_len = 0;
+  if_data.ifc_buf = NULL;
+
+  // Open a (random) socket to have a file descriptor for the ioctl calls.
+  fd = _Jv_socket (PF_INET, SOCK_DGRAM, htons (IPPROTO_IP));
+
+  if (fd < 0)
+    throw new ::java::net::SocketException;
+
+  // Get all interfaces. If not enough buffers are available try it
+  // with a bigger buffer size.
+  do
+    {
+      num_interfaces += 16;
+      
+      if_data.ifc_len = sizeof (struct ifreq) * num_interfaces;
+      if_data.ifc_buf =
+        (char*) _Jv_Realloc (if_data.ifc_buf, if_data.ifc_len);
+
+      // Try to get all local interfaces.
+      if (::ioctl (fd, SIOCGIFCONF, &if_data) < 0)
+        throw new java::net::SocketException;
+    }
+  while (if_data.ifc_len >= (sizeof (struct ifreq) * num_interfaces));
+
+  // Get addresses of all interfaces.
+  if_record = if_data.ifc_req;
+
+  for (int n = 0; n < if_data.ifc_len; n += sizeof (struct ifreq))
+    {
+      struct ifreq ifr;
+      
+      memset (&ifr, 0, sizeof (ifr));
+      strcpy (ifr.ifr_name, if_record->ifr_name);
+
+      // Try to get the IPv4-address of the local interface
+      if (::ioctl (fd, SIOCGIFADDR, &ifr) < 0)
+        throw new java::net::SocketException;
+
+      int len = 4;
+      struct sockaddr_in sa = *((sockaddr_in*) &(ifr.ifr_addr));
+
+      jbyteArray baddr = JvNewByteArray (len);
+      memcpy (elements (baddr), &(sa.sin_addr), len);
+      jstring if_name = JvNewStringLatin1 (if_record->ifr_name);
+      Inet4Address* address =
+        new java::net::Inet4Address (baddr, JvNewStringLatin1 (""));
+      ht->add (new NetworkInterface (if_name, address));
+      if_record++;
+    }
+
+#ifdef HAVE_INET6
+      // FIXME: read /proc/net/if_inet6 (on Linux 2.4)
+#endif
+
+  _Jv_Free (if_data.ifc_buf);
+  
+  if (fd >= 0)
+    _Jv_close (fd);
+  
+  return ht;
+}
+
+#endif // DISABLE_JAVA_NET //
Index: java/net/natNetworkInterfaceWin32.cc
===================================================================
RCS file: java/net/natNetworkInterfaceWin32.cc
diff -N java/net/natNetworkInterfaceWin32.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/net/natNetworkInterfaceWin32.cc	14 Mar 2003 08:30:44 -0000
@@ -0,0 +1,142 @@
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#ifdef WIN32
+
+#include <windows.h>
+#include <winsock.h>
+#undef STRICT
+
+#else /* WIN32 */
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#define BSD_COMP /* Get FIONREAD on Solaris2. */
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+
+#endif /* WIN32 */
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/net/NetworkInterface.h>
+#include <java/net/Inet4Address.h>
+#include <java/net/SocketException.h>
+#include <java/util/Vector.h>
+
+#ifdef DISABLE_JAVA_NET
+
+::java::util::Vector*
+java::net::NetworkInterface::getRealNetworkInterfaces ()
+{
+  ::java::util::Vector* ht = new ::java::util::Vector();
+  return ht;
+}
+
+#else /* DISABLE_JAVA_NET */
+
+::java::util::Vector*
+java::net::NetworkInterface::getRealNetworkInterfaces ()
+{
+#ifdef WIN32
+  throw new ::java::net::SocketException;
+#else
+  int fd;
+  int num_interfaces = 0;
+  struct ifconf if_data;
+  struct ifreq* if_record;
+  ::java::util::Vector* ht = new ::java::util::Vector ();
+
+  if_data.ifc_len = 0;
+  if_data.ifc_buf = NULL;
+
+  // Open a (random) socket to have a file descriptor for the ioctl calls.
+  fd = _Jv_socket (PF_INET, SOCK_DGRAM, htons (IPPROTO_IP));
+
+  if (fd < 0)
+    throw new ::java::net::SocketException;
+
+  // Get all interfaces. If not enough buffers are available try it
+  // with a bigger buffer size.
+  do
+    {
+      num_interfaces += 16;
+      
+      if_data.ifc_len = sizeof (struct ifreq) * num_interfaces;
+      if_data.ifc_buf =
+        (char*) _Jv_Realloc (if_data.ifc_buf, if_data.ifc_len);
+
+      // Try to get all local interfaces.
+      if (::ioctl (fd, SIOCGIFCONF, &if_data) < 0)
+        throw new java::net::SocketException;
+    }
+  while (if_data.ifc_len >= (sizeof (struct ifreq) * num_interfaces));
+
+  // Get addresses of all interfaces.
+  if_record = if_data.ifc_req;
+
+  for (int n = 0; n < if_data.ifc_len; n += sizeof (struct ifreq))
+    {
+      struct ifreq ifr;
+      
+      memset (&ifr, 0, sizeof (ifr));
+      strcpy (ifr.ifr_name, if_record->ifr_name);
+
+      // Try to get the IPv4-address of the local interface
+      if (::ioctl (fd, SIOCGIFADDR, &ifr) < 0)
+        throw new java::net::SocketException;
+
+      int len = 4;
+      struct sockaddr_in sa = *((sockaddr_in*) &(ifr.ifr_addr));
+
+      jbyteArray baddr = JvNewByteArray (len);
+      memcpy (elements (baddr), &(sa.sin_addr), len);
+      jstring if_name = JvNewStringLatin1 (if_record->ifr_name);
+      Inet4Address* address =
+        new java::net::Inet4Address (baddr, JvNewStringLatin1 (""));
+      ht->add (new NetworkInterface (if_name, address));
+      if_record++;
+    }
+
+#ifdef HAVE_INET6
+      // FIXME: read /proc/net/if_inet6 (on Linux 2.4)
+#endif
+
+  _Jv_Free (if_data.ifc_buf);
+  
+  if (fd >= 0)
+    _Jv_close (fd);
+  
+  return ht;
+#endif /* WIN32 */
+}
+
+#endif // DISABLE_JAVA_NET //
Index: java/net/natPlainDatagramSocketImplEcos.cc
===================================================================
RCS file: java/net/natPlainDatagramSocketImplEcos.cc
diff -N java/net/natPlainDatagramSocketImplEcos.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/net/natPlainDatagramSocketImplEcos.cc	14 Mar 2003 08:30:44 -0000
@@ -0,0 +1,119 @@
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#include <java/io/IOException.h>
+#include <java/lang/Object.h>
+#include <java/net/BindException.h>
+#include <java/net/DatagramPacketInetAddress.h>
+#include <java/net/InetAddress.h>
+#include <java/net/NetworkInterface.h>
+#include <java/net/PlainDatagramSocketImpl.h>
+#include <java/net/SocketException.h>
+
+void
+java::net::PlainDatagramSocketImpl::create ()
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.create: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::bind (jint, java::net::InetAddress *)
+{
+  throw new BindException (
+    JvNewStringLatin1 ("DatagramSocketImpl.bind: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::connect (java::net::InetAddress *, jint)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.connect: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::disconnect ()
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.disconnect: unimplemented"));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.peek: unimplemented"));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::peekData(java::net::DatagramPacket *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.peekData: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::close ()
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.close: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.send: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.receive: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::setTimeToLive (jint)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.setTimeToLive: unimplemented"));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::getTimeToLive ()
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.getTimeToLive: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *,
+                                              java::net::NetworkInterface *,
+					      jboolean)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.mcastGrp: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::setOption (jint, java::lang::Object *)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.setOption: unimplemented"));
+}
+
+java::lang::Object *
+java::net::PlainDatagramSocketImpl::getOption (jint)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.getOption: unimplemented"));
+}
Index: java/net/natPlainDatagramSocketImplPosix.cc
===================================================================
RCS file: java/net/natPlainDatagramSocketImplPosix.cc
diff -N java/net/natPlainDatagramSocketImplPosix.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/net/natPlainDatagramSocketImplPosix.cc	14 Mar 2003 08:30:44 -0000
@@ -0,0 +1,857 @@
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#include <errno.h>
+#include <string.h>
+
+#if HAVE_BSTRING_H
+// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2 
+#include <bstring.h>
+#endif
+
+#include <gcj/cni.h>
+#include <java/io/IOException.h>
+#include <java/io/InterruptedIOException.h>
+#include <java/net/BindException.h>
+#include <java/net/SocketException.h>
+#include <java/net/PlainDatagramSocketImpl.h>
+#include <java/net/InetAddress.h>
+#include <java/net/NetworkInterface.h>
+#include <java/net/DatagramPacket.h>
+#include <java/net/PortUnreachableException.h>
+#include <java/lang/InternalError.h>
+#include <java/lang/Object.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Integer.h>
+
+#ifdef DISABLE_JAVA_NET
+
+void
+java::net::PlainDatagramSocketImpl::create ()
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.create: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::bind (jint, java::net::InetAddress *)
+{
+  throw new BindException (
+    JvNewStringLatin1 ("DatagramSocketImpl.bind: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::connect (java::net::InetAddress *, jint)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.connect: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::disconnect ()
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.disconnect: unimplemented"));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.peek: unimplemented"));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::peekData(java::net::DatagramPacket *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.peekData: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::close ()
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.close: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.send: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.receive: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::setTimeToLive (jint)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.setTimeToLive: unimplemented"));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::getTimeToLive ()
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.getTimeToLive: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *,
+                                              java::net::NetworkInterface *,
+					      jboolean)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.mcastGrp: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::setOption (jint, java::lang::Object *)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.setOption: unimplemented"));
+}
+
+java::lang::Object *
+java::net::PlainDatagramSocketImpl::getOption (jint)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.getOption: unimplemented"));
+}
+
+#else /* DISABLE_JAVA_NET */
+
+
+union SockAddr
+{
+  struct sockaddr_in address;
+#ifdef HAVE_INET6
+  struct sockaddr_in6 address6;
+#endif
+};
+
+union McastReq
+{
+#if HAVE_STRUCT_IP_MREQ
+  struct ip_mreq mreq;
+#endif
+#if HAVE_STRUCT_IPV6_MREQ
+  struct ipv6_mreq mreq6;
+#endif
+};
+
+union InAddr
+{
+  struct in_addr addr;
+#ifdef HAVE_INET6
+  struct in6_addr addr6;
+#endif
+};
+
+
+// FIXME: routines here and/or in natPlainSocketImpl.cc could throw
+// NoRouteToHostException; also consider UnknownHostException, ConnectException.
+
+void
+java::net::PlainDatagramSocketImpl::create ()
+{
+  int sock = _Jv_socket (AF_INET, SOCK_DGRAM, 0);
+
+  if (sock < 0)
+    {
+      char* strerr = strerror (errno);
+      throw new java::net::SocketException (JvNewStringUTF (strerr));
+    }
+
+  _Jv_platform_close_on_exec (sock);
+
+  // We use fnum in place of fd here.  From leaving fd null we avoid
+  // the double close problem in FileDescriptor.finalize.
+  fnum = sock;
+}
+
+void
+java::net::PlainDatagramSocketImpl::bind (jint lport,
+					  java::net::InetAddress *host)
+{
+  union SockAddr u;
+  struct sockaddr *ptr = (struct sockaddr *) &u.address;
+  // FIXME: Use getaddrinfo() to get actual protocol instead of assuming ipv4.
+  jbyteArray haddress = host->addr;
+  jbyte *bytes = elements (haddress);
+  int len = haddress->length;
+
+  if (len == 4)
+    {
+      u.address.sin_family = AF_INET;
+
+      if (host != NULL)
+        memcpy (&u.address.sin_addr, bytes, len);
+      else
+        u.address.sin_addr.s_addr = htonl (INADDR_ANY);
+
+      len = sizeof (struct sockaddr_in);
+      u.address.sin_port = htons (lport);
+    }
+#ifdef HAVE_INET6
+  else if (len == 16)
+    {
+      u.address6.sin6_family = AF_INET6;
+      memcpy (&u.address6.sin6_addr, bytes, len);
+      len = sizeof (struct sockaddr_in6);
+      u.address6.sin6_port = htons (lport);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid length"));
+
+  if (_Jv_bind (fnum, ptr, len) == 0)
+    {
+      socklen_t addrlen = sizeof(u);
+
+      if (lport != 0)
+        localPort = lport;
+      else if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0)
+        localPort = ntohs (u.address.sin_port);
+      else
+        goto error;
+
+      /* Allow broadcast by default. */
+      int broadcast = 1;
+      if (::setsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &broadcast, 
+                        sizeof (broadcast)) != 0)
+        goto error;
+
+      return;
+    }
+
+ error:
+  char* strerr = strerror (errno);
+  throw new java::net::BindException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainDatagramSocketImpl::connect (java::net::InetAddress *, jint)
+{ 
+  throw new ::java::lang::InternalError (JvNewStringLatin1 (
+	    "PlainDatagramSocketImpl::connect: not implemented yet"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::disconnect ()
+{
+  throw new ::java::lang::InternalError (JvNewStringLatin1 (
+	    "PlainDatagramSocketImpl::disconnect: not implemented yet"));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *i)
+{
+  // FIXME: Deal with Multicast and if the socket is connected.
+  union SockAddr u;
+  socklen_t addrlen = sizeof(u);
+  ssize_t retlen =
+    ::recvfrom (fnum, (char *) NULL, 0, MSG_PEEK, (sockaddr*) &u,
+      &addrlen);
+  if (retlen < 0)
+    goto error;
+  // FIXME: Deal with Multicast addressing and if the socket is connected.
+  jbyteArray raddr;
+  jint rport;
+  if (u.address.sin_family == AF_INET)
+    {
+      raddr = JvNewByteArray (4);
+      memcpy (elements (raddr), &u.address.sin_addr, 4);
+      rport = ntohs (u.address.sin_port);
+    }
+#ifdef HAVE_INET6
+  else if (u.address.sin_family == AF_INET6)
+    {
+      raddr = JvNewByteArray (16);
+      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
+      rport = ntohs (u.address6.sin6_port);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid family"));
+
+  i->addr = raddr;
+  return rport;
+ error:
+  char* strerr = strerror (errno);
+
+  if (errno == ECONNREFUSED)
+    throw new PortUnreachableException (JvNewStringUTF (strerr));
+
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::peekData(java::net::DatagramPacket *p)
+{
+  // FIXME: Deal with Multicast and if the socket is connected.
+  union SockAddr u;
+  socklen_t addrlen = sizeof(u);
+  jbyte *dbytes = elements (p->getData());
+  ssize_t retlen = 0;
+
+  // Do timeouts via select since SO_RCVTIMEO is not always available.
+  if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
+    {
+      fd_set rset;
+      struct timeval tv;
+      FD_ZERO(&rset);
+      FD_SET(fnum, &rset);
+      tv.tv_sec = timeout / 1000;
+      tv.tv_usec = (timeout % 1000) * 1000;
+      int retval;
+      if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0)
+        goto error;
+      else if (retval == 0)
+        throw new java::io::InterruptedIOException ();
+    }
+
+  retlen =
+    ::recvfrom (fnum, (char *) dbytes, p->getLength(), MSG_PEEK, (sockaddr*) &u,
+      &addrlen);
+  if (retlen < 0)
+    goto error;
+  // FIXME: Deal with Multicast addressing and if the socket is connected.
+  jbyteArray raddr;
+  jint rport;
+  if (u.address.sin_family == AF_INET)
+    {
+      raddr = JvNewByteArray (4);
+      memcpy (elements (raddr), &u.address.sin_addr, 4);
+      rport = ntohs (u.address.sin_port);
+    }
+#ifdef HAVE_INET6
+  else if (u.address.sin_family == AF_INET6)
+    {
+      raddr = JvNewByteArray (16);
+      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
+      rport = ntohs (u.address6.sin6_port);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid family"));
+
+  p->setAddress (new InetAddress (raddr, NULL));
+  p->setPort (rport);
+  p->setLength ((jint) retlen);
+  return rport;
+
+ error:
+  char* strerr = strerror (errno);
+
+  if (errno == ECONNREFUSED)
+    throw new PortUnreachableException (JvNewStringUTF (strerr));
+
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+// Close(shutdown) the socket.
+void
+java::net::PlainDatagramSocketImpl::close ()
+{
+  // Avoid races from asynchronous finalization.
+  JvSynchronize sync (this);
+
+  // The method isn't declared to throw anything, so we disregard
+  // the return value.
+  _Jv_close (fnum);
+  fnum = -1;
+  timeout = 0;
+}
+
+void
+java::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *p)
+{
+  // FIXME: Deal with Multicast and if the socket is connected.
+  jint rport = p->getPort();
+  union SockAddr u;
+  jbyteArray haddress = p->getAddress()->addr;
+  jbyte *bytes = elements (haddress);
+  int len = haddress->length;
+  struct sockaddr *ptr = (struct sockaddr *) &u.address;
+  jbyte *dbytes = elements (p->getData());
+  if (len == 4)
+    {
+      u.address.sin_family = AF_INET;
+      memcpy (&u.address.sin_addr, bytes, len);
+      len = sizeof (struct sockaddr_in);
+      u.address.sin_port = htons (rport);
+    }
+#ifdef HAVE_INET6
+  else if (len == 16)
+    {
+      u.address6.sin6_family = AF_INET6;
+      memcpy (&u.address6.sin6_addr, bytes, len);
+      len = sizeof (struct sockaddr_in6);
+      u.address6.sin6_port = htons (rport);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid length"));
+
+  if (::sendto (fnum, (char *) dbytes, p->getLength(), 0, ptr, len) >= 0)
+    return;
+
+  char* strerr = strerror (errno);
+
+  if (errno == ECONNREFUSED)
+    throw new PortUnreachableException (JvNewStringUTF (strerr));
+
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *p)
+{
+  // FIXME: Deal with Multicast and if the socket is connected.
+  union SockAddr u;
+  socklen_t addrlen = sizeof(u);
+  jbyte *dbytes = elements (p->getData());
+  ssize_t retlen = 0;
+
+  // Do timeouts via select since SO_RCVTIMEO is not always available.
+  if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
+    {
+      fd_set rset;
+      struct timeval tv;
+      FD_ZERO(&rset);
+      FD_SET(fnum, &rset);
+      tv.tv_sec = timeout / 1000;
+      tv.tv_usec = (timeout % 1000) * 1000;
+      int retval;
+      if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0)
+        goto error;
+      else if (retval == 0)
+        throw new java::io::InterruptedIOException ();
+    }
+
+  retlen =
+    ::recvfrom (fnum, (char *) dbytes, p->getLength(), 0, (sockaddr*) &u,
+      &addrlen);
+  if (retlen < 0)
+    goto error;
+  // FIXME: Deal with Multicast addressing and if the socket is connected.
+  jbyteArray raddr;
+  jint rport;
+  if (u.address.sin_family == AF_INET)
+    {
+      raddr = JvNewByteArray (4);
+      memcpy (elements (raddr), &u.address.sin_addr, 4);
+      rport = ntohs (u.address.sin_port);
+    }
+#ifdef HAVE_INET6
+  else if (u.address.sin_family == AF_INET6)
+    {
+      raddr = JvNewByteArray (16);
+      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
+      rport = ntohs (u.address6.sin6_port);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid family"));
+
+  p->setAddress (new InetAddress (raddr, NULL));
+  p->setPort (rport);
+  p->setLength ((jint) retlen);
+  return;
+
+ error:
+  char* strerr = strerror (errno);
+
+  if (errno == ECONNREFUSED)
+    throw new PortUnreachableException (JvNewStringUTF (strerr));
+
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainDatagramSocketImpl::setTimeToLive (jint ttl)
+{
+  // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4.
+  char val = (char) ttl;
+  socklen_t val_len = sizeof(val);
+
+  if (::setsockopt (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, val_len) == 0)
+    return;
+
+  char* strerr = strerror (errno);
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::getTimeToLive ()
+{
+  // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4.
+  char val;
+  socklen_t val_len = sizeof(val);
+
+  if (::getsockopt (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, &val_len) == 0)
+    return ((int) val) & 0xFF;
+
+  char* strerr = strerror (errno);
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *inetaddr,
+                                              java::net::NetworkInterface *,
+					      jboolean join)
+{
+  // FIXME: implement use of NetworkInterface
+
+  union McastReq u;
+  jbyteArray haddress = inetaddr->addr;
+  jbyte *bytes = elements (haddress);
+  int len = haddress->length;
+  int level, opname;
+  const char *ptr;
+  if (0)
+    ;
+#if HAVE_STRUCT_IP_MREQ
+  else if (len == 4)
+    {
+      level = IPPROTO_IP;
+      opname = join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
+      memcpy (&u.mreq.imr_multiaddr, bytes, len);
+      // FIXME:  If a non-default interface is set, use it; see Stevens p. 501.
+      // Maybe not, see note in last paragraph at bottom of Stevens p. 497.
+      u.mreq.imr_interface.s_addr = htonl (INADDR_ANY); 
+      len = sizeof (struct ip_mreq);
+      ptr = (const char *) &u.mreq;
+    }
+#endif
+#if HAVE_STRUCT_IPV6_MREQ
+  else if (len == 16)
+    {
+      level = IPPROTO_IPV6;
+
+      /* Prefer new RFC 2553 names.  */
+#ifndef IPV6_JOIN_GROUP
+#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
+#endif
+#ifndef IPV6_LEAVE_GROUP
+#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
+#endif
+
+      opname = join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP;
+      memcpy (&u.mreq6.ipv6mr_multiaddr, bytes, len);
+      // FIXME:  If a non-default interface is set, use it; see Stevens p. 501.
+      // Maybe not, see note in last paragraph at bottom of Stevens p. 497.
+      u.mreq6.ipv6mr_interface = 0;
+      len = sizeof (struct ipv6_mreq);
+      ptr = (const char *) &u.mreq6;
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid length"));
+
+  if (::setsockopt (fnum, level, opname, ptr, len) == 0)
+    return;
+
+  char* strerr = strerror (errno);
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainDatagramSocketImpl::setOption (jint optID,
+					       java::lang::Object *value)
+{
+  int val;
+  socklen_t val_len = sizeof (val);
+
+  if (fnum < 0)
+    throw new java::net::SocketException (JvNewStringUTF ("Socket closed"));
+
+  if (_Jv_IsInstanceOf (value, &java::lang::Boolean::class$))
+    {
+      java::lang::Boolean *boolobj = 
+        static_cast<java::lang::Boolean *> (value);
+      val = boolobj->booleanValue() ? 1 : 0;
+    }
+  else if (_Jv_IsInstanceOf (value, &java::lang::Integer::class$))
+    {
+      java::lang::Integer *intobj = 
+        static_cast<java::lang::Integer *> (value);          
+      val = (int) intobj->intValue();
+    }
+  // Else assume value to be an InetAddress for use with IP_MULTICAST_IF.
+
+  switch (optID) 
+    {
+      case _Jv_TCP_NODELAY_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
+        return;
+      case _Jv_SO_LINGER_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_LINGER not valid for UDP"));
+        return;
+      case _Jv_SO_KEEPALIVE_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
+        return;
+
+      case _Jv_SO_BROADCAST_ :
+        if (::setsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val,
+                          val_len) != 0)
+          goto error;
+	break;
+	
+      case _Jv_SO_OOBINLINE_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_OOBINLINE: not valid for UDP"));
+        break;
+	
+      case _Jv_SO_SNDBUF_ :
+      case _Jv_SO_RCVBUF_ :
+#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
+        int opt;
+        optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
+        if (::setsockopt (fnum, SOL_SOCKET, opt, (char *) &val, val_len) != 0)
+	  goto error;    
+#else
+        throw new java::lang::InternalError (
+          JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
+#endif 
+        return;
+      case _Jv_SO_REUSEADDR_ :
+#if defined(SO_REUSEADDR)
+	if (::setsockopt (fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
+	    val_len) != 0)
+	  goto error;
+#else
+        throw new java::lang::InternalError (
+          JvNewStringUTF ("SO_REUSEADDR not supported"));
+#endif 
+	return;
+      case _Jv_SO_BINDADDR_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_BINDADDR: read only option"));
+        return;
+      case _Jv_IP_MULTICAST_IF_ :
+	union InAddr u;
+        jbyteArray haddress;
+	jbyte *bytes;
+	int len;
+	int level, opname;
+	const char *ptr;
+
+	haddress = ((java::net::InetAddress *) value)->addr;
+	bytes = elements (haddress);
+	len = haddress->length;
+	if (len == 4)
+	  {
+	    level = IPPROTO_IP;
+	    opname = IP_MULTICAST_IF;
+	    memcpy (&u.addr, bytes, len);
+	    len = sizeof (struct in_addr);
+	    ptr = (const char *) &u.addr;
+	  }
+// Tru64 UNIX V5.0 has struct sockaddr_in6, but no IPV6_MULTICAST_IF
+#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_IF)
+	else if (len == 16)
+	  {
+	    level = IPPROTO_IPV6;
+	    opname = IPV6_MULTICAST_IF;
+	    memcpy (&u.addr6, bytes, len);
+	    len = sizeof (struct in6_addr);
+	    ptr = (const char *) &u.addr6;
+	  }
+#endif
+	else
+	  throw
+	    new java::net::SocketException (JvNewStringUTF ("invalid length"));
+
+	if (::setsockopt (fnum, level, opname, ptr, len) != 0)
+	  goto error;
+        return;
+	
+      case _Jv_IP_MULTICAST_IF2_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
+        break;
+	
+      case _Jv_IP_MULTICAST_LOOP_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("IP_MULTICAST_LOOP: not yet implemented"));
+        break;
+	
+      case _Jv_IP_TOS_ :
+        if (::setsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val,
+	   val_len) != 0)
+	  goto error;    
+	return;
+	
+      case _Jv_SO_TIMEOUT_ :
+	timeout = val;
+        return;
+      default :
+        errno = ENOPROTOOPT;
+    }
+
+ error:
+  char* strerr = strerror (errno);
+  throw new java::net::SocketException (JvNewStringUTF (strerr));
+}
+
+java::lang::Object *
+java::net::PlainDatagramSocketImpl::getOption (jint optID)
+{
+  int val;
+  socklen_t val_len = sizeof(val);
+  union SockAddr u;
+  socklen_t addrlen = sizeof(u);
+
+  switch (optID)
+    {
+      case _Jv_TCP_NODELAY_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
+        break;
+      case _Jv_SO_LINGER_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_LINGER not valid for UDP"));
+        break;    
+      case _Jv_SO_KEEPALIVE_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
+        break;
+	
+      case _Jv_SO_BROADCAST_ :
+	if (::getsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val,
+	    &val_len) != 0)
+	  goto error;
+	return new java::lang::Boolean (val != 0);
+	
+      case _Jv_SO_OOBINLINE_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_OOBINLINE not valid for UDP"));
+        break;
+      
+      case _Jv_SO_RCVBUF_ :
+      case _Jv_SO_SNDBUF_ :
+#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
+        int opt;
+        optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
+        if (::getsockopt (fnum, SOL_SOCKET, opt, (char *) &val, &val_len) != 0)
+	  goto error;    
+        else
+	  return new java::lang::Integer (val);
+#else
+        throw new java::lang::InternalError (
+          JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
+#endif    
+	break;
+      case _Jv_SO_BINDADDR_:
+	// cache the local address
+	if (localAddress == NULL)
+	  {	
+	    jbyteArray laddr;
+	    if (::getsockname (fnum, (sockaddr*) &u, &addrlen) != 0)
+	      goto error;
+	    if (u.address.sin_family == AF_INET)
+	      {
+		laddr = JvNewByteArray (4);
+		memcpy (elements (laddr), &u.address.sin_addr, 4);
+	      }
+#ifdef HAVE_INET6
+            else if (u.address.sin_family == AF_INET6)
+	      {
+		laddr = JvNewByteArray (16);
+		memcpy (elements (laddr), &u.address6.sin6_addr, 16);
+	      }
+#endif
+	    else
+	      throw new java::net::SocketException (
+			      JvNewStringUTF ("invalid family"));
+	    localAddress = new java::net::InetAddress (laddr, NULL);
+	  }
+	return localAddress;  
+	break;
+      case _Jv_SO_REUSEADDR_ :
+#if defined(SO_REUSEADDR)
+	if (::getsockopt (fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
+	    &val_len) != 0)
+	  goto error;
+	return new java::lang::Boolean (val != 0);
+#else
+        throw new java::lang::InternalError (
+          JvNewStringUTF ("SO_REUSEADDR not supported"));
+#endif 
+	break;
+      case _Jv_IP_MULTICAST_IF_ :
+#ifdef HAVE_INET_NTOA
+	struct in_addr inaddr;
+  	socklen_t inaddr_len;
+	char *bytes;
+
+  	inaddr_len = sizeof(inaddr);
+	if (::getsockopt (fnum, IPPROTO_IP, IP_MULTICAST_IF, (char *) &inaddr,
+	    &inaddr_len) != 0)
+	  goto error;
+
+	bytes = inet_ntoa (inaddr);
+
+	return java::net::InetAddress::getByName (JvNewStringLatin1 (bytes));
+#else
+	throw new java::net::SocketException (
+	  JvNewStringUTF ("IP_MULTICAST_IF: not available - no inet_ntoa()"));
+#endif
+	break;
+      case _Jv_SO_TIMEOUT_ :
+	return new java::lang::Integer (timeout);
+	break;
+	
+      case _Jv_IP_MULTICAST_IF2_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
+        break;
+	
+      case _Jv_IP_MULTICAST_LOOP_ :
+	if (::getsockopt (fnum, SOL_SOCKET, IP_MULTICAST_LOOP, (char *) &val,
+	    &val_len) != 0)
+	  goto error;
+	return new java::lang::Boolean (val != 0);
+	
+      case _Jv_IP_TOS_ :
+        if (::getsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val,
+           &val_len) != 0)
+          goto error;
+        return new java::lang::Integer (val);
+	
+      default :
+	errno = ENOPROTOOPT;
+    }
+
+ error:
+  char* strerr = strerror (errno);
+  throw new java::net::SocketException (JvNewStringUTF (strerr));
+}
+
+#endif /* DISABLE_JAVA_NET */
Index: java/net/natPlainDatagramSocketImplWin32.cc
===================================================================
RCS file: java/net/natPlainDatagramSocketImplWin32.cc
diff -N java/net/natPlainDatagramSocketImplWin32.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/net/natPlainDatagramSocketImplWin32.cc	14 Mar 2003 08:30:44 -0000
@@ -0,0 +1,872 @@
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#ifdef WIN32
+
+#include <errno.h>
+#include <string.h>
+
+#else /* WIN32 */
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#include <errno.h>
+#include <string.h>
+
+#endif /* WIN32 */
+
+#if HAVE_BSTRING_H
+// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2 
+#include <bstring.h>
+#endif
+
+#include <gcj/cni.h>
+#include <java/io/IOException.h>
+#include <java/io/InterruptedIOException.h>
+#include <java/net/BindException.h>
+#include <java/net/SocketException.h>
+#include <java/net/PlainDatagramSocketImpl.h>
+#include <java/net/InetAddress.h>
+#include <java/net/NetworkInterface.h>
+#include <java/net/DatagramPacket.h>
+#include <java/net/PortUnreachableException.h>
+#include <java/lang/InternalError.h>
+#include <java/lang/Object.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Integer.h>
+
+#ifdef DISABLE_JAVA_NET
+
+void
+java::net::PlainDatagramSocketImpl::create ()
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.create: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::bind (jint, java::net::InetAddress *)
+{
+  throw new BindException (
+    JvNewStringLatin1 ("DatagramSocketImpl.bind: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::connect (java::net::InetAddress *, jint)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.connect: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::disconnect ()
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.disconnect: unimplemented"));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.peek: unimplemented"));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::peekData(java::net::DatagramPacket *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.peekData: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::close ()
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.close: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.send: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.receive: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::setTimeToLive (jint)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.setTimeToLive: unimplemented"));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::getTimeToLive ()
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.getTimeToLive: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *,
+                                              java::net::NetworkInterface *,
+					      jboolean)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("DatagramSocketImpl.mcastGrp: unimplemented"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::setOption (jint, java::lang::Object *)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.setOption: unimplemented"));
+}
+
+java::lang::Object *
+java::net::PlainDatagramSocketImpl::getOption (jint)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("DatagramSocketImpl.getOption: unimplemented"));
+}
+
+#else /* DISABLE_JAVA_NET */
+
+
+union SockAddr
+{
+  struct sockaddr_in address;
+#ifdef HAVE_INET6
+  struct sockaddr_in6 address6;
+#endif
+};
+
+union McastReq
+{
+#if HAVE_STRUCT_IP_MREQ
+  struct ip_mreq mreq;
+#endif
+#if HAVE_STRUCT_IPV6_MREQ
+  struct ipv6_mreq mreq6;
+#endif
+};
+
+union InAddr
+{
+  struct in_addr addr;
+#ifdef HAVE_INET6
+  struct in6_addr addr6;
+#endif
+};
+
+
+// FIXME: routines here and/or in natPlainSocketImpl.cc could throw
+// NoRouteToHostException; also consider UnknownHostException, ConnectException.
+
+void
+java::net::PlainDatagramSocketImpl::create ()
+{
+  int sock = _Jv_socket (AF_INET, SOCK_DGRAM, 0);
+
+  if (sock < 0)
+    {
+      char* strerr = strerror (errno);
+      throw new java::net::SocketException (JvNewStringUTF (strerr));
+    }
+
+  _Jv_platform_close_on_exec (sock);
+
+  // We use fnum in place of fd here.  From leaving fd null we avoid
+  // the double close problem in FileDescriptor.finalize.
+  fnum = sock;
+}
+
+void
+java::net::PlainDatagramSocketImpl::bind (jint lport,
+					  java::net::InetAddress *host)
+{
+  union SockAddr u;
+  struct sockaddr *ptr = (struct sockaddr *) &u.address;
+  // FIXME: Use getaddrinfo() to get actual protocol instead of assuming ipv4.
+  jbyteArray haddress = host->addr;
+  jbyte *bytes = elements (haddress);
+  int len = haddress->length;
+
+  if (len == 4)
+    {
+      u.address.sin_family = AF_INET;
+
+      if (host != NULL)
+        memcpy (&u.address.sin_addr, bytes, len);
+      else
+        u.address.sin_addr.s_addr = htonl (INADDR_ANY);
+
+      len = sizeof (struct sockaddr_in);
+      u.address.sin_port = htons (lport);
+    }
+#ifdef HAVE_INET6
+  else if (len == 16)
+    {
+      u.address6.sin6_family = AF_INET6;
+      memcpy (&u.address6.sin6_addr, bytes, len);
+      len = sizeof (struct sockaddr_in6);
+      u.address6.sin6_port = htons (lport);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid length"));
+
+  if (_Jv_bind (fnum, ptr, len) == 0)
+    {
+      socklen_t addrlen = sizeof(u);
+
+      if (lport != 0)
+        localPort = lport;
+      else if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0)
+        localPort = ntohs (u.address.sin_port);
+      else
+        goto error;
+
+      /* Allow broadcast by default. */
+      int broadcast = 1;
+      if (::setsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &broadcast, 
+                        sizeof (broadcast)) != 0)
+        goto error;
+
+      return;
+    }
+
+ error:
+  char* strerr = strerror (errno);
+  throw new java::net::BindException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainDatagramSocketImpl::connect (java::net::InetAddress *, jint)
+{ 
+  throw new ::java::lang::InternalError (JvNewStringLatin1 (
+	    "PlainDatagramSocketImpl::connect: not implemented yet"));
+}
+
+void
+java::net::PlainDatagramSocketImpl::disconnect ()
+{
+  throw new ::java::lang::InternalError (JvNewStringLatin1 (
+	    "PlainDatagramSocketImpl::disconnect: not implemented yet"));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::peek (java::net::InetAddress *i)
+{
+  // FIXME: Deal with Multicast and if the socket is connected.
+  union SockAddr u;
+  socklen_t addrlen = sizeof(u);
+  ssize_t retlen =
+    ::recvfrom (fnum, (char *) NULL, 0, MSG_PEEK, (sockaddr*) &u,
+      &addrlen);
+  if (retlen < 0)
+    goto error;
+  // FIXME: Deal with Multicast addressing and if the socket is connected.
+  jbyteArray raddr;
+  jint rport;
+  if (u.address.sin_family == AF_INET)
+    {
+      raddr = JvNewByteArray (4);
+      memcpy (elements (raddr), &u.address.sin_addr, 4);
+      rport = ntohs (u.address.sin_port);
+    }
+#ifdef HAVE_INET6
+  else if (u.address.sin_family == AF_INET6)
+    {
+      raddr = JvNewByteArray (16);
+      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
+      rport = ntohs (u.address6.sin6_port);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid family"));
+
+  i->addr = raddr;
+  return rport;
+ error:
+  char* strerr = strerror (errno);
+
+  if (errno == ECONNREFUSED)
+    throw new PortUnreachableException (JvNewStringUTF (strerr));
+
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::peekData(java::net::DatagramPacket *p)
+{
+  // FIXME: Deal with Multicast and if the socket is connected.
+  union SockAddr u;
+  socklen_t addrlen = sizeof(u);
+  jbyte *dbytes = elements (p->getData());
+  ssize_t retlen = 0;
+
+// FIXME: implement timeout support for Win32
+#ifndef WIN32
+  // Do timeouts via select since SO_RCVTIMEO is not always available.
+  if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
+    {
+      fd_set rset;
+      struct timeval tv;
+      FD_ZERO(&rset);
+      FD_SET(fnum, &rset);
+      tv.tv_sec = timeout / 1000;
+      tv.tv_usec = (timeout % 1000) * 1000;
+      int retval;
+      if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0)
+        goto error;
+      else if (retval == 0)
+        throw new java::io::InterruptedIOException ();
+    }
+#endif /* WIN32 */
+
+  retlen =
+    ::recvfrom (fnum, (char *) dbytes, p->getLength(), MSG_PEEK, (sockaddr*) &u,
+      &addrlen);
+  if (retlen < 0)
+    goto error;
+  // FIXME: Deal with Multicast addressing and if the socket is connected.
+  jbyteArray raddr;
+  jint rport;
+  if (u.address.sin_family == AF_INET)
+    {
+      raddr = JvNewByteArray (4);
+      memcpy (elements (raddr), &u.address.sin_addr, 4);
+      rport = ntohs (u.address.sin_port);
+    }
+#ifdef HAVE_INET6
+  else if (u.address.sin_family == AF_INET6)
+    {
+      raddr = JvNewByteArray (16);
+      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
+      rport = ntohs (u.address6.sin6_port);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid family"));
+
+  p->setAddress (new InetAddress (raddr, NULL));
+  p->setPort (rport);
+  p->setLength ((jint) retlen);
+  return rport;
+
+ error:
+  char* strerr = strerror (errno);
+
+  if (errno == ECONNREFUSED)
+    throw new PortUnreachableException (JvNewStringUTF (strerr));
+
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+// Close(shutdown) the socket.
+void
+java::net::PlainDatagramSocketImpl::close ()
+{
+  // Avoid races from asynchronous finalization.
+  JvSynchronize sync (this);
+
+  // The method isn't declared to throw anything, so we disregard
+  // the return value.
+  _Jv_close (fnum);
+  fnum = -1;
+  timeout = 0;
+}
+
+void
+java::net::PlainDatagramSocketImpl::send (java::net::DatagramPacket *p)
+{
+  // FIXME: Deal with Multicast and if the socket is connected.
+  jint rport = p->getPort();
+  union SockAddr u;
+  jbyteArray haddress = p->getAddress()->addr;
+  jbyte *bytes = elements (haddress);
+  int len = haddress->length;
+  struct sockaddr *ptr = (struct sockaddr *) &u.address;
+  jbyte *dbytes = elements (p->getData());
+  if (len == 4)
+    {
+      u.address.sin_family = AF_INET;
+      memcpy (&u.address.sin_addr, bytes, len);
+      len = sizeof (struct sockaddr_in);
+      u.address.sin_port = htons (rport);
+    }
+#ifdef HAVE_INET6
+  else if (len == 16)
+    {
+      u.address6.sin6_family = AF_INET6;
+      memcpy (&u.address6.sin6_addr, bytes, len);
+      len = sizeof (struct sockaddr_in6);
+      u.address6.sin6_port = htons (rport);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid length"));
+
+  if (::sendto (fnum, (char *) dbytes, p->getLength(), 0, ptr, len) >= 0)
+    return;
+
+  char* strerr = strerror (errno);
+
+  if (errno == ECONNREFUSED)
+    throw new PortUnreachableException (JvNewStringUTF (strerr));
+
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainDatagramSocketImpl::receive (java::net::DatagramPacket *p)
+{
+  // FIXME: Deal with Multicast and if the socket is connected.
+  union SockAddr u;
+  socklen_t addrlen = sizeof(u);
+  jbyte *dbytes = elements (p->getData());
+  ssize_t retlen = 0;
+
+// FIXME: implement timeout support for Win32
+#ifndef WIN32
+  // Do timeouts via select since SO_RCVTIMEO is not always available.
+  if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
+    {
+      fd_set rset;
+      struct timeval tv;
+      FD_ZERO(&rset);
+      FD_SET(fnum, &rset);
+      tv.tv_sec = timeout / 1000;
+      tv.tv_usec = (timeout % 1000) * 1000;
+      int retval;
+      if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0)
+        goto error;
+      else if (retval == 0)
+        throw new java::io::InterruptedIOException ();
+    }
+#endif /* WIN32 */
+
+  retlen =
+    ::recvfrom (fnum, (char *) dbytes, p->getLength(), 0, (sockaddr*) &u,
+      &addrlen);
+  if (retlen < 0)
+    goto error;
+  // FIXME: Deal with Multicast addressing and if the socket is connected.
+  jbyteArray raddr;
+  jint rport;
+  if (u.address.sin_family == AF_INET)
+    {
+      raddr = JvNewByteArray (4);
+      memcpy (elements (raddr), &u.address.sin_addr, 4);
+      rport = ntohs (u.address.sin_port);
+    }
+#ifdef HAVE_INET6
+  else if (u.address.sin_family == AF_INET6)
+    {
+      raddr = JvNewByteArray (16);
+      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
+      rport = ntohs (u.address6.sin6_port);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid family"));
+
+  p->setAddress (new InetAddress (raddr, NULL));
+  p->setPort (rport);
+  p->setLength ((jint) retlen);
+  return;
+
+ error:
+  char* strerr = strerror (errno);
+
+  if (errno == ECONNREFUSED)
+    throw new PortUnreachableException (JvNewStringUTF (strerr));
+
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainDatagramSocketImpl::setTimeToLive (jint ttl)
+{
+  // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4.
+  char val = (char) ttl;
+  socklen_t val_len = sizeof(val);
+
+  if (::setsockopt (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, val_len) == 0)
+    return;
+
+  char* strerr = strerror (errno);
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+jint
+java::net::PlainDatagramSocketImpl::getTimeToLive ()
+{
+  // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4.
+  char val;
+  socklen_t val_len = sizeof(val);
+
+  if (::getsockopt (fnum, IPPROTO_IP, IP_MULTICAST_TTL, &val, &val_len) == 0)
+    return ((int) val) & 0xFF;
+
+  char* strerr = strerror (errno);
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainDatagramSocketImpl::mcastGrp (java::net::InetAddress *inetaddr,
+                                              java::net::NetworkInterface *,
+					      jboolean join)
+{
+  // FIXME: implement use of NetworkInterface
+
+  union McastReq u;
+  jbyteArray haddress = inetaddr->addr;
+  jbyte *bytes = elements (haddress);
+  int len = haddress->length;
+  int level, opname;
+  const char *ptr;
+  if (0)
+    ;
+#if HAVE_STRUCT_IP_MREQ
+  else if (len == 4)
+    {
+      level = IPPROTO_IP;
+      opname = join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
+      memcpy (&u.mreq.imr_multiaddr, bytes, len);
+      // FIXME:  If a non-default interface is set, use it; see Stevens p. 501.
+      // Maybe not, see note in last paragraph at bottom of Stevens p. 497.
+      u.mreq.imr_interface.s_addr = htonl (INADDR_ANY); 
+      len = sizeof (struct ip_mreq);
+      ptr = (const char *) &u.mreq;
+    }
+#endif
+#if HAVE_STRUCT_IPV6_MREQ
+  else if (len == 16)
+    {
+      level = IPPROTO_IPV6;
+
+      /* Prefer new RFC 2553 names.  */
+#ifndef IPV6_JOIN_GROUP
+#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
+#endif
+#ifndef IPV6_LEAVE_GROUP
+#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
+#endif
+
+      opname = join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP;
+      memcpy (&u.mreq6.ipv6mr_multiaddr, bytes, len);
+      // FIXME:  If a non-default interface is set, use it; see Stevens p. 501.
+      // Maybe not, see note in last paragraph at bottom of Stevens p. 497.
+      u.mreq6.ipv6mr_interface = 0;
+      len = sizeof (struct ipv6_mreq);
+      ptr = (const char *) &u.mreq6;
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid length"));
+
+  if (::setsockopt (fnum, level, opname, ptr, len) == 0)
+    return;
+
+  char* strerr = strerror (errno);
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainDatagramSocketImpl::setOption (jint optID,
+					       java::lang::Object *value)
+{
+  int val;
+  socklen_t val_len = sizeof (val);
+
+  if (fnum < 0)
+    throw new java::net::SocketException (JvNewStringUTF ("Socket closed"));
+
+  if (_Jv_IsInstanceOf (value, &java::lang::Boolean::class$))
+    {
+      java::lang::Boolean *boolobj = 
+        static_cast<java::lang::Boolean *> (value);
+      val = boolobj->booleanValue() ? 1 : 0;
+    }
+  else if (_Jv_IsInstanceOf (value, &java::lang::Integer::class$))
+    {
+      java::lang::Integer *intobj = 
+        static_cast<java::lang::Integer *> (value);          
+      val = (int) intobj->intValue();
+    }
+  // Else assume value to be an InetAddress for use with IP_MULTICAST_IF.
+
+  switch (optID) 
+    {
+      case _Jv_TCP_NODELAY_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
+        return;
+      case _Jv_SO_LINGER_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_LINGER not valid for UDP"));
+        return;
+      case _Jv_SO_KEEPALIVE_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
+        return;
+
+      case _Jv_SO_BROADCAST_ :
+        if (::setsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val,
+                          val_len) != 0)
+          goto error;
+	break;
+	
+      case _Jv_SO_OOBINLINE_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_OOBINLINE: not valid for UDP"));
+        break;
+	
+      case _Jv_SO_SNDBUF_ :
+      case _Jv_SO_RCVBUF_ :
+#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
+        int opt;
+        optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
+        if (::setsockopt (fnum, SOL_SOCKET, opt, (char *) &val, val_len) != 0)
+	  goto error;    
+#else
+        throw new java::lang::InternalError (
+          JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
+#endif 
+        return;
+      case _Jv_SO_REUSEADDR_ :
+#if defined(SO_REUSEADDR)
+	if (::setsockopt (fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
+	    val_len) != 0)
+	  goto error;
+#else
+        throw new java::lang::InternalError (
+          JvNewStringUTF ("SO_REUSEADDR not supported"));
+#endif 
+	return;
+      case _Jv_SO_BINDADDR_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_BINDADDR: read only option"));
+        return;
+      case _Jv_IP_MULTICAST_IF_ :
+	union InAddr u;
+        jbyteArray haddress;
+	jbyte *bytes;
+	int len;
+	int level, opname;
+	const char *ptr;
+
+	haddress = ((java::net::InetAddress *) value)->addr;
+	bytes = elements (haddress);
+	len = haddress->length;
+	if (len == 4)
+	  {
+	    level = IPPROTO_IP;
+	    opname = IP_MULTICAST_IF;
+	    memcpy (&u.addr, bytes, len);
+	    len = sizeof (struct in_addr);
+	    ptr = (const char *) &u.addr;
+	  }
+// Tru64 UNIX V5.0 has struct sockaddr_in6, but no IPV6_MULTICAST_IF
+#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_IF)
+	else if (len == 16)
+	  {
+	    level = IPPROTO_IPV6;
+	    opname = IPV6_MULTICAST_IF;
+	    memcpy (&u.addr6, bytes, len);
+	    len = sizeof (struct in6_addr);
+	    ptr = (const char *) &u.addr6;
+	  }
+#endif
+	else
+	  throw
+	    new java::net::SocketException (JvNewStringUTF ("invalid length"));
+
+	if (::setsockopt (fnum, level, opname, ptr, len) != 0)
+	  goto error;
+        return;
+	
+      case _Jv_IP_MULTICAST_IF2_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
+        break;
+	
+      case _Jv_IP_MULTICAST_LOOP_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("IP_MULTICAST_LOOP: not yet implemented"));
+        break;
+	
+      case _Jv_IP_TOS_ :
+        if (::setsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val,
+	   val_len) != 0)
+	  goto error;    
+	return;
+	
+      case _Jv_SO_TIMEOUT_ :
+	timeout = val;
+        return;
+      default :
+        errno = ENOPROTOOPT;
+    }
+
+ error:
+  char* strerr = strerror (errno);
+  throw new java::net::SocketException (JvNewStringUTF (strerr));
+}
+
+java::lang::Object *
+java::net::PlainDatagramSocketImpl::getOption (jint optID)
+{
+  int val;
+  socklen_t val_len = sizeof(val);
+  union SockAddr u;
+  socklen_t addrlen = sizeof(u);
+
+  switch (optID)
+    {
+      case _Jv_TCP_NODELAY_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
+        break;
+      case _Jv_SO_LINGER_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_LINGER not valid for UDP"));
+        break;    
+      case _Jv_SO_KEEPALIVE_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
+        break;
+	
+      case _Jv_SO_BROADCAST_ :
+	if (::getsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val,
+	    &val_len) != 0)
+	  goto error;
+	return new java::lang::Boolean (val != 0);
+	
+      case _Jv_SO_OOBINLINE_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_OOBINLINE not valid for UDP"));
+        break;
+      
+      case _Jv_SO_RCVBUF_ :
+      case _Jv_SO_SNDBUF_ :
+#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
+        int opt;
+        optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
+        if (::getsockopt (fnum, SOL_SOCKET, opt, (char *) &val, &val_len) != 0)
+	  goto error;    
+        else
+	  return new java::lang::Integer (val);
+#else
+        throw new java::lang::InternalError (
+          JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
+#endif    
+	break;
+      case _Jv_SO_BINDADDR_:
+	// cache the local address
+	if (localAddress == NULL)
+	  {	
+	    jbyteArray laddr;
+	    if (::getsockname (fnum, (sockaddr*) &u, &addrlen) != 0)
+	      goto error;
+	    if (u.address.sin_family == AF_INET)
+	      {
+		laddr = JvNewByteArray (4);
+		memcpy (elements (laddr), &u.address.sin_addr, 4);
+	      }
+#ifdef HAVE_INET6
+            else if (u.address.sin_family == AF_INET6)
+	      {
+		laddr = JvNewByteArray (16);
+		memcpy (elements (laddr), &u.address6.sin6_addr, 16);
+	      }
+#endif
+	    else
+	      throw new java::net::SocketException (
+			      JvNewStringUTF ("invalid family"));
+	    localAddress = new java::net::InetAddress (laddr, NULL);
+	  }
+	return localAddress;  
+	break;
+      case _Jv_SO_REUSEADDR_ :
+#if defined(SO_REUSEADDR)
+	if (::getsockopt (fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
+	    &val_len) != 0)
+	  goto error;
+	return new java::lang::Boolean (val != 0);
+#else
+        throw new java::lang::InternalError (
+          JvNewStringUTF ("SO_REUSEADDR not supported"));
+#endif 
+	break;
+      case _Jv_IP_MULTICAST_IF_ :
+#ifdef HAVE_INET_NTOA
+	struct in_addr inaddr;
+  	socklen_t inaddr_len;
+	char *bytes;
+
+  	inaddr_len = sizeof(inaddr);
+	if (::getsockopt (fnum, IPPROTO_IP, IP_MULTICAST_IF, (char *) &inaddr,
+	    &inaddr_len) != 0)
+	  goto error;
+
+	bytes = inet_ntoa (inaddr);
+
+	return java::net::InetAddress::getByName (JvNewStringLatin1 (bytes));
+#else
+	throw new java::net::SocketException (
+	  JvNewStringUTF ("IP_MULTICAST_IF: not available - no inet_ntoa()"));
+#endif
+	break;
+      case _Jv_SO_TIMEOUT_ :
+	return new java::lang::Integer (timeout);
+	break;
+	
+      case _Jv_IP_MULTICAST_IF2_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
+        break;
+	
+      case _Jv_IP_MULTICAST_LOOP_ :
+	if (::getsockopt (fnum, SOL_SOCKET, IP_MULTICAST_LOOP, (char *) &val,
+	    &val_len) != 0)
+	  goto error;
+	return new java::lang::Boolean (val != 0);
+	
+      case _Jv_IP_TOS_ :
+        if (::getsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val,
+           &val_len) != 0)
+          goto error;
+        return new java::lang::Integer (val);
+	
+      default :
+	errno = ENOPROTOOPT;
+    }
+
+ error:
+  char* strerr = strerror (errno);
+  throw new java::net::SocketException (JvNewStringUTF (strerr));
+}
+
+#endif /* DISABLE_JAVA_NET */
Index: java/net/natPlainSocketImplEcos.cc
===================================================================
RCS file: java/net/natPlainSocketImplEcos.cc
diff -N java/net/natPlainSocketImplEcos.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/net/natPlainSocketImplEcos.cc	14 Mar 2003 08:30:44 -0000
@@ -0,0 +1,124 @@
+/* Copyright (C) 2003 Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#include <java/net/PlainSocketImpl.h>
+
+void
+java::net::PlainSocketImpl::create (jboolean)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("SocketImpl.create: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::bind (java::net::InetAddress *, jint)
+{
+  throw new BindException (
+    JvNewStringLatin1 ("SocketImpl.bind: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::connect (java::net::SocketAddress *, jint)
+{
+  throw new ConnectException (
+    JvNewStringLatin1 ("SocketImpl.connect: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::listen (jint)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("SocketImpl.listen: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("SocketImpl.accept: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::setOption (jint, java::lang::Object *)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.setOption: unimplemented"));
+}
+
+java::lang::Object *
+java::net::PlainSocketImpl::getOption (jint)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.getOption: unimplemented"));
+}
+
+jint
+java::net::PlainSocketImpl::read(void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.read: unimplemented"));
+}
+
+jint
+java::net::PlainSocketImpl::read(jbyteArray buffer, jint offset, jint count)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.read: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::write(jint b)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.write: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::write(jbyteArray b, jint offset, jint len)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.write: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::sendUrgentData(jint data)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.sendUrgentData: unimplemented"));
+}
+
+jint
+java::net::PlainSocketImpl::available(void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.available: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::close(void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.close: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::shutdownInput (void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.shutdownInput: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::shutdownOutput (void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.shutdownOutput: unimplemented"));
+}
Index: java/net/natPlainSocketImplPosix.cc
===================================================================
RCS file: java/net/natPlainSocketImplPosix.cc
diff -N java/net/natPlainSocketImplPosix.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/net/natPlainSocketImplPosix.cc	14 Mar 2003 08:30:44 -0000
@@ -0,0 +1,978 @@
+/* Copyright (C) 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#ifndef DISABLE_JAVA_NET
+
+#ifdef HAVE_SYS_IOCTL_H
+#define BSD_COMP /* Get FIONREAD on Solaris2. */
+#include <sys/ioctl.h>
+#endif
+
+// Pick up FIONREAD on Solaris 2.5.
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <errno.h>
+#include <string.h>
+
+#endif /* DISABLE_JAVA_NET */
+
+#if HAVE_BSTRING_H
+// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2 
+#include <bstring.h>
+#endif
+
+#include <gcj/cni.h>
+#include <gcj/javaprims.h>
+#include <java/io/IOException.h>
+#include <java/io/InterruptedIOException.h>
+#include <java/net/BindException.h>
+#include <java/net/ConnectException.h>
+#include <java/net/PlainSocketImpl.h>
+#include <java/net/InetAddress.h>
+#include <java/net/InetSocketAddress.h>
+#include <java/net/SocketException.h>
+#include <java/net/SocketTimeoutException.h>
+#include <java/lang/InternalError.h>
+#include <java/lang/Object.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Class.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Thread.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalArgumentException.h>
+
+#ifdef DISABLE_JAVA_NET
+
+void
+java::net::PlainSocketImpl::create (jboolean)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("SocketImpl.create: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::bind (java::net::InetAddress *, jint)
+{
+  throw new BindException (
+    JvNewStringLatin1 ("SocketImpl.bind: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::connect (java::net::SocketAddress *, jint)
+{
+  throw new ConnectException (
+    JvNewStringLatin1 ("SocketImpl.connect: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::listen (jint)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("SocketImpl.listen: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("SocketImpl.accept: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::setOption (jint, java::lang::Object *)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.setOption: unimplemented"));
+}
+
+java::lang::Object *
+java::net::PlainSocketImpl::getOption (jint)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.getOption: unimplemented"));
+}
+
+jint
+java::net::PlainSocketImpl::read(void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.read: unimplemented"));
+}
+
+jint
+java::net::PlainSocketImpl::read(jbyteArray buffer, jint offset, jint count)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.read: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::write(jint b)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.write: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::write(jbyteArray b, jint offset, jint len)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.write: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::sendUrgentData(jint data)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.sendUrgentData: unimplemented"));
+}
+
+jint
+java::net::PlainSocketImpl::available(void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.available: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::close(void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.close: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::shutdownInput (void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.shutdownInput: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::shutdownOutput (void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.shutdownOutput: unimplemented"));
+}
+
+#else /* DISABLE_JAVA_NET */
+
+union SockAddr
+{
+  struct sockaddr_in address;
+#ifdef HAVE_INET6
+  struct sockaddr_in6 address6;
+#endif
+};
+
+void
+java::net::PlainSocketImpl::create (jboolean stream)
+{
+  int sock = _Jv_socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
+
+  if (sock < 0)
+    {
+      char* strerr = strerror (errno);
+      throw new java::io::IOException (JvNewStringUTF (strerr));
+    }
+
+  _Jv_platform_close_on_exec (sock);
+
+  // We use fnum in place of fd here.  From leaving fd null we avoid
+  // the double close problem in FileDescriptor.finalize.
+  fnum = sock;
+}
+
+void
+java::net::PlainSocketImpl::bind (java::net::InetAddress *host, jint lport)
+{
+  union SockAddr u;
+  struct sockaddr *ptr = (struct sockaddr *) &u.address;
+  jbyteArray haddress = host->addr;
+  jbyte *bytes = elements (haddress);
+  int len = haddress->length;
+  int i = 1;
+
+  if (len == 4)
+    {
+      u.address.sin_family = AF_INET;
+
+      if (host != NULL)
+        memcpy (&u.address.sin_addr, bytes, len);
+      else
+        u.address.sin_addr.s_addr = htonl (INADDR_ANY);
+
+      len = sizeof (struct sockaddr_in);
+      u.address.sin_port = htons (lport);
+    }
+#ifdef HAVE_INET6
+  else if (len == 16)
+    {
+      u.address6.sin6_family = AF_INET6;
+      memcpy (&u.address6.sin6_addr, bytes, len);
+      len = sizeof (struct sockaddr_in6);
+      u.address6.sin6_port = htons (lport);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid length"));
+
+  // Enable SO_REUSEADDR, so that servers can reuse ports left in TIME_WAIT.
+  ::setsockopt(fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof(i));
+  
+  if (_Jv_bind (fnum, ptr, len) == 0)
+    {
+      address = host;
+      socklen_t addrlen = sizeof(u);
+
+      if (lport != 0)
+        localport = lport;
+      else if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0)
+        localport = ntohs (u.address.sin_port);
+      else
+        goto error;
+
+      return;
+    }
+
+ error:
+  char* strerr = strerror (errno);
+  throw new java::net::BindException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainSocketImpl::connect (java::net::SocketAddress *addr,
+                                     jint timeout)
+{
+  java::net::InetSocketAddress *tmp = (java::net::InetSocketAddress*) addr;
+  java::net::InetAddress *host = tmp->getAddress();
+  jint rport = tmp->getPort();
+	
+  union SockAddr u;
+  socklen_t addrlen = sizeof(u);
+  jbyteArray haddress = host->addr;
+  jbyte *bytes = elements (haddress);
+  int len = haddress->length;
+  struct sockaddr *ptr = (struct sockaddr *) &u.address;
+  if (len == 4)
+    {
+      u.address.sin_family = AF_INET;
+      memcpy (&u.address.sin_addr, bytes, len);
+      len = sizeof (struct sockaddr_in);
+      u.address.sin_port = htons (rport);
+    }
+#ifdef HAVE_INET6
+  else if (len == 16)
+    {
+      u.address6.sin6_family = AF_INET6;
+      memcpy (&u.address6.sin6_addr, bytes, len);
+      len = sizeof (struct sockaddr_in6);
+      u.address6.sin6_port = htons (rport);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid length"));
+
+  if (timeout > 0)
+    {
+      int flags = ::fcntl (fnum, F_GETFL);
+      ::fcntl (fnum, F_SETFL, flags | O_NONBLOCK);
+      
+      if ((_Jv_connect (fnum, ptr, len) != 0) && (errno != EINPROGRESS))
+        goto error;
+
+      fd_set rset;
+      struct timeval tv;
+      FD_ZERO(&rset);
+      FD_SET(fnum, &rset);
+      tv.tv_sec = timeout / 1000;
+      tv.tv_usec = (timeout % 1000) * 1000;
+      int retval;
+      
+      if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0)
+        goto error;
+      else if (retval == 0)
+        throw new java::net::SocketTimeoutException
+          (JvNewStringUTF ("Connect timed out"));
+    }
+  else
+    {
+      if (_Jv_connect (fnum, ptr, len) != 0)
+        goto error;
+    }
+
+  address = host;
+  port = rport;
+
+  // A bind may not have been done on this socket; if so, set localport now.
+  if (localport == 0)
+    {
+      if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0)
+        localport = ntohs (u.address.sin_port);
+      else
+        goto error;
+    }
+
+  return;  
+
+ error:
+  char* strerr = strerror (errno);
+  throw new java::net::ConnectException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainSocketImpl::listen (jint backlog)
+{
+  if (::listen (fnum, backlog) != 0)
+    {
+      char* strerr = strerror (errno);
+      throw new java::io::IOException (JvNewStringUTF (strerr));
+    }
+}
+
+void
+java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *s)
+{
+  union SockAddr u;
+  socklen_t addrlen = sizeof(u);
+  int new_socket = 0; 
+
+  // Do timeouts via select since SO_RCVTIMEO is not always available.
+  if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
+    {
+      fd_set rset;
+      struct timeval tv;
+      FD_ZERO(&rset);
+      FD_SET(fnum, &rset);
+      tv.tv_sec = timeout / 1000;
+      tv.tv_usec = (timeout % 1000) * 1000;
+      int retval;
+      if ((retval = _Jv_select (fnum + 1, &rset, NULL, NULL, &tv)) < 0)
+        goto error;
+      else if (retval == 0)
+        throw new java::io::InterruptedIOException (
+	                                  JvNewStringUTF("Accept timed out"));
+    }
+
+  new_socket = _Jv_accept (fnum, (sockaddr*) &u, &addrlen);
+
+  if (new_socket < 0)
+    goto error;
+
+  _Jv_platform_close_on_exec (new_socket);
+
+  jbyteArray raddr;
+  jint rport;
+  if (u.address.sin_family == AF_INET)
+    {
+      raddr = JvNewByteArray (4);
+      memcpy (elements (raddr), &u.address.sin_addr, 4);
+      rport = ntohs (u.address.sin_port);
+    }
+#ifdef HAVE_INET6
+  else if (u.address.sin_family == AF_INET6)
+    {
+      raddr = JvNewByteArray (16);
+      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
+      rport = ntohs (u.address6.sin6_port);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid family"));
+
+  s->fnum = new_socket;
+  s->localport = localport;
+  s->address = new InetAddress (raddr, NULL);
+  s->port = rport;
+  return;
+
+ error:
+  char* strerr = strerror (errno);
+  throw new java::io::IOException (JvNewStringUTF (strerr));
+}
+
+// Close(shutdown) the socket.
+void
+java::net::PlainSocketImpl::close()
+{
+  // Avoid races from asynchronous finalization.
+  JvSynchronize sync (this);
+
+  // should we use shutdown here? how would that effect so_linger?
+  int res = _Jv_close (fnum);
+
+  if (res == -1)
+    {
+      // These three errors are not errors according to tests performed
+      // on the reference implementation.
+      if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF)
+        throw new java::io::IOException  (JvNewStringUTF (strerror (errno)));
+    }
+  // Safe place to reset the file pointer.
+  fnum = -1;
+  timeout = 0;
+}
+
+// Write a byte to the socket.
+void
+java::net::PlainSocketImpl::write(jint b)
+{
+  jbyte d =(jbyte) b;
+  int r = 0;
+
+  while (r != 1)
+    {
+      r = _Jv_write (fnum, &d, 1);
+      if (r == -1)
+        {
+          if (java::lang::Thread::interrupted())
+            {
+              java::io::InterruptedIOException *iioe
+                = new java::io::InterruptedIOException 
+                (JvNewStringLatin1 (strerror (errno)));
+              iioe->bytesTransferred = 0;
+              throw iioe;
+            }
+          // Some errors should not cause exceptions.
+          if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF)
+            throw new java::io::IOException (JvNewStringUTF (strerror (errno)));
+          break;
+        }
+    }
+}
+
+// Write some bytes to the socket.
+void
+java::net::PlainSocketImpl::write(jbyteArray b, jint offset, jint len)
+{
+  if (! b)
+    throw new java::lang::NullPointerException;
+  if (offset < 0 || len < 0 || offset + len > JvGetArrayLength (b))
+    throw new java::lang::ArrayIndexOutOfBoundsException;
+
+  jbyte *bytes = elements (b) + offset;
+  int written = 0;
+
+  while (len > 0)
+    {
+      int r = _Jv_write (fnum, bytes, len);
+
+      if (r == -1)
+        {
+          if (java::lang::Thread::interrupted())
+            {
+              java::io::InterruptedIOException *iioe
+                = new java::io::InterruptedIOException
+                (JvNewStringLatin1 (strerror (errno)));
+              iioe->bytesTransferred = written;
+              throw iioe;
+            }
+          // Some errors should not cause exceptions.
+          if (errno != ENOTCONN && errno != ECONNRESET && errno != EBADF)
+            throw new java::io::IOException (JvNewStringUTF (strerror (errno)));
+          break;
+        }
+
+      written += r;
+      len -= r;
+      bytes += r;
+    }
+}
+
+void
+java::net::PlainSocketImpl::sendUrgentData (jint)
+{
+  throw new SocketException (JvNewStringLatin1 (
+    "PlainSocketImpl: sending of urgent data not supported by this socket"));
+}
+
+// Read a single byte from the socket.
+jint
+java::net::PlainSocketImpl::read(void)
+{
+  jbyte b;
+
+  // Do timeouts via select.
+  if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
+    {
+      // Create the file descriptor set.
+      fd_set read_fds;
+      FD_ZERO (&read_fds);
+      FD_SET (fnum,&read_fds);
+      // Create the timeout struct based on our internal timeout value.
+      struct timeval timeout_value;
+      timeout_value.tv_sec = timeout / 1000;
+      timeout_value.tv_usec = (timeout % 1000) * 1000;
+      // Select on the fds.
+      int sel_retval =
+        _Jv_select (fnum + 1, &read_fds, NULL, NULL, &timeout_value);
+      // If select returns 0 we've waited without getting data...
+      // that means we've timed out.
+      if (sel_retval == 0)
+        throw new java::io::InterruptedIOException
+          (JvNewStringUTF ("read timed out") );
+      // If select returns ok we know we either got signalled or read some data...
+      // either way we need to try to read.
+    }
+
+  int r = _Jv_read (fnum, &b, 1);
+
+  if (r == 0)
+    return -1;
+
+  if (java::lang::Thread::interrupted())
+    {
+      java::io::InterruptedIOException *iioe =
+        new java::io::InterruptedIOException
+        (JvNewStringUTF("read interrupted"));
+      iioe->bytesTransferred = r == -1 ? 0 : r;
+      throw iioe;
+    }
+  else if (r == -1)
+    {
+      // Some errors cause us to return end of stream...
+      if (errno == ENOTCONN)
+        return -1;
+
+      // Other errors need to be signalled.
+      throw new java::io::IOException (JvNewStringUTF (strerror (errno)));
+    }
+
+  return b & 0xFF;
+}
+
+// Read count bytes into the buffer, starting at offset.
+jint
+java::net::PlainSocketImpl::read(jbyteArray buffer, jint offset, jint count)
+{
+  if (! buffer)
+    throw new java::lang::NullPointerException;
+
+  jsize bsize = JvGetArrayLength (buffer);
+
+  if (offset < 0 || count < 0 || offset + count > bsize)
+    throw new java::lang::ArrayIndexOutOfBoundsException;
+
+  jbyte *bytes = elements (buffer) + offset;
+
+  // Do timeouts via select.
+  if (timeout > 0 && fnum >= 0 && fnum < FD_SETSIZE)
+    {
+      // Create the file descriptor set.
+      fd_set read_fds;
+      FD_ZERO (&read_fds);
+      FD_SET (fnum, &read_fds);
+      // Create the timeout struct based on our internal timeout value.
+      struct timeval timeout_value;
+      timeout_value.tv_sec = timeout / 1000;
+      timeout_value.tv_usec =(timeout % 1000) * 1000;
+      // Select on the fds.
+      int sel_retval =
+        _Jv_select (fnum + 1, &read_fds, NULL, NULL, &timeout_value);
+      // We're only interested in the 0 return.
+      // error returns still require us to try to read 
+      // the socket to see what happened.
+      if (sel_retval == 0)
+        {
+          java::io::InterruptedIOException *iioe =
+            new java::io::InterruptedIOException
+            (JvNewStringUTF ("read interrupted"));
+          iioe->bytesTransferred = 0;
+          throw iioe;
+        }
+    }
+
+  // Read the socket.
+  int r = ::recv (fnum, (char *) bytes, count, 0);
+
+  if (r == 0)
+    return -1;
+
+  if (java::lang::Thread::interrupted())
+    {
+      java::io::InterruptedIOException *iioe =
+        new java::io::InterruptedIOException
+        (JvNewStringUTF ("read interrupted"));
+      iioe->bytesTransferred = r == -1 ? 0 : r;
+      throw iioe;
+    }
+  else if (r == -1)
+    {
+      // Some errors cause us to return end of stream...
+      if (errno == ENOTCONN)
+        return -1;
+
+      // Other errors need to be signalled.
+      throw new java::io::IOException (JvNewStringUTF (strerror (errno)));
+    }
+
+  return r;
+}
+
+// How many bytes are available?
+jint
+java::net::PlainSocketImpl::available(void)
+{
+#if defined(FIONREAD) || defined(HAVE_SELECT)
+  long num = 0;
+  int r = 0;
+  bool num_set = false;
+
+#if defined(FIONREAD)
+  r = ::ioctl (fnum, FIONREAD, &num);
+
+  if (r == -1 && errno == ENOTTY)
+    {
+      // If the ioctl doesn't work, we don't care.
+      r = 0;
+      num = 0;
+    }
+  else
+    num_set = true;
+#elif defined(HAVE_SELECT)
+  if (fnum < 0)
+    {
+      errno = EBADF;
+      r = -1;
+    }
+#endif
+
+  if (r == -1)
+    {
+    posix_error:
+      throw new java::io::IOException(JvNewStringUTF(strerror(errno)));
+    }
+
+  // If we didn't get anything we can use select.
+
+#if defined(HAVE_SELECT)
+  if (! num_set)
+    if (! num_set && fnum >= 0 && fnum < FD_SETSIZE)
+      {
+        fd_set rd;
+        FD_ZERO (&rd);
+        FD_SET (fnum, &rd);
+        struct timeval tv;
+        tv.tv_sec = 0;
+        tv.tv_usec = 0;
+        r = _Jv_select (fnum + 1, &rd, NULL, NULL, &tv);
+        if(r == -1)
+          goto posix_error;
+        num = r == 0 ? 0 : 1;
+      }
+#endif /* HAVE_SELECT */
+
+  return (jint) num;
+#else
+  throw new java::io::IOException (JvNewStringUTF ("unimplemented"));
+#endif
+}
+
+void
+java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value)
+{
+  int val;
+  socklen_t val_len = sizeof (val);
+
+  if (fnum < 0)
+    throw new java::net::SocketException (JvNewStringUTF ("Socket closed"));
+
+  if (_Jv_IsInstanceOf (value, &java::lang::Boolean::class$))
+    {
+      java::lang::Boolean *boolobj = 
+        static_cast<java::lang::Boolean *> (value);
+      if (boolobj->booleanValue())
+        val = 1; 
+      else 
+        {
+          if (optID == _Jv_SO_LINGER_)
+            val = -1;
+          else
+            val = 0;
+        }
+    }
+  else if (_Jv_IsInstanceOf (value, &java::lang::Integer::class$))
+    {
+      java::lang::Integer *intobj = 
+        static_cast<java::lang::Integer *> (value);          
+      val = (int) intobj->intValue();
+    }
+  else
+    {
+      throw new java::lang::IllegalArgumentException (
+        JvNewStringLatin1 ("`value' must be Boolean or Integer"));
+    }
+
+  switch (optID) 
+    {
+      case _Jv_TCP_NODELAY_ :
+#ifdef TCP_NODELAY
+        if (::setsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val,
+                          val_len) != 0)
+          goto error;
+#else
+        throw new java::lang::InternalError
+          (JvNewStringUTF ("TCP_NODELAY not supported"));
+#endif /* TCP_NODELAY */
+        return;
+
+      case _Jv_SO_KEEPALIVE_ :
+        if (::setsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val,
+                          val_len) != 0)
+          goto error;
+        break;
+      
+      case _Jv_SO_BROADCAST_ :
+        throw new java::net::SocketException
+          (JvNewStringUTF ("SO_BROADCAST not valid for TCP"));
+        break;
+	
+      case _Jv_SO_OOBINLINE_ :
+        if (::setsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val,
+                          val_len) != 0)
+          goto error;
+        break;
+
+      case _Jv_SO_LINGER_ :
+#ifdef SO_LINGER
+        struct linger l_val;
+        l_val.l_onoff = (val != -1);
+        l_val.l_linger = val;
+
+        if (::setsockopt (fnum, SOL_SOCKET, SO_LINGER, (char *) &l_val,
+                          sizeof(l_val)) != 0)
+          goto error;    
+#else
+        throw new java::lang::InternalError (
+          JvNewStringUTF ("SO_LINGER not supported"));
+#endif /* SO_LINGER */
+        return;
+
+      case _Jv_SO_SNDBUF_ :
+      case _Jv_SO_RCVBUF_ :
+#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
+        int opt;
+        optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
+        if (::setsockopt (fnum, SOL_SOCKET, opt, (char *) &val, val_len) != 0)
+          goto error;    
+#else
+        throw new java::lang::InternalError (
+          JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
+#endif 
+        return;
+
+      case _Jv_SO_BINDADDR_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_BINDADDR: read only option"));
+        return;
+
+      case _Jv_IP_MULTICAST_IF_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP"));
+        return;
+	
+      case _Jv_IP_MULTICAST_IF2_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP"));
+        break;
+	
+      case _Jv_IP_MULTICAST_LOOP_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP"));
+        break;
+	
+      case _Jv_IP_TOS_ :
+        if (::setsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val,
+                          val_len) != 0)
+          goto error;    
+        break;
+	
+      case _Jv_SO_REUSEADDR_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_REUSEADDR: not valid for TCP"));
+        return;
+
+      case _Jv_SO_TIMEOUT_ :
+        timeout = val;
+        return;
+
+      default :
+        errno = ENOPROTOOPT;
+    }
+
+ error:
+  char* strerr = strerror (errno);
+  throw new java::net::SocketException (JvNewStringUTF (strerr));
+}
+
+java::lang::Object *
+java::net::PlainSocketImpl::getOption (jint optID)
+{
+  int val;
+  socklen_t val_len = sizeof(val);
+  union SockAddr u;
+  socklen_t addrlen = sizeof(u);
+  struct linger l_val;
+  socklen_t l_val_len = sizeof(l_val);
+
+  switch (optID)
+    {
+#ifdef TCP_NODELAY
+    case _Jv_TCP_NODELAY_ :
+      if (::getsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val,
+                        &val_len) != 0)
+        goto error;
+      else
+        return new java::lang::Boolean (val != 0);
+#else
+      throw new java::lang::InternalError
+        (JvNewStringUTF ("TCP_NODELAY not supported"));
+#endif       
+      break;
+      
+    case _Jv_SO_LINGER_ :
+#ifdef SO_LINGER
+      if (::getsockopt (fnum, SOL_SOCKET, SO_LINGER, (char *) &l_val,
+                        &l_val_len) != 0)
+        goto error;    
+ 
+      if (l_val.l_onoff)
+        return new java::lang::Integer (l_val.l_linger);
+      else
+        return new java::lang::Boolean ((jboolean)false);
+#else
+      throw new java::lang::InternalError
+        (JvNewStringUTF ("SO_LINGER not supported"));
+#endif
+      break;    
+
+    case _Jv_SO_KEEPALIVE_ :
+      if (::getsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val,
+                        &val_len) != 0)
+        goto error;
+      else
+        return new java::lang::Boolean (val != 0);
+
+    case _Jv_SO_BROADCAST_ :
+      if (::getsockopt (fnum, SOL_SOCKET, SO_BROADCAST, (char *) &val,
+                        &val_len) != 0)
+        goto error;    
+      return new java::lang::Boolean ((jboolean)val);
+	
+    case _Jv_SO_OOBINLINE_ :
+      if (::getsockopt (fnum, SOL_SOCKET, SO_OOBINLINE, (char *) &val,
+                        &val_len) != 0)
+        goto error;    
+      return new java::lang::Boolean ((jboolean)val);
+	
+    case _Jv_SO_RCVBUF_ :
+    case _Jv_SO_SNDBUF_ :
+#if defined(SO_SNDBUF) && defined(SO_RCVBUF)
+      int opt;
+      optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
+      if (::getsockopt (fnum, SOL_SOCKET, opt, (char *) &val, &val_len) != 0)
+        goto error;    
+      else
+        return new java::lang::Integer (val);
+#else
+      throw new java::lang::InternalError
+        (JvNewStringUTF ("SO_RCVBUF/SO_SNDBUF not supported"));
+#endif    
+      break;
+    case _Jv_SO_BINDADDR_:
+      // cache the local address 
+      if (localAddress == NULL)
+        {
+          jbyteArray laddr;
+
+          if (::getsockname (fnum, (sockaddr*) &u, &addrlen) != 0)
+            goto error;
+
+          if (u.address.sin_family == AF_INET)
+            {
+              laddr = JvNewByteArray (4);
+              memcpy (elements (laddr), &u.address.sin_addr, 4);
+            }
+#ifdef HAVE_INET6
+          else if (u.address.sin_family == AF_INET6)
+            {
+              laddr = JvNewByteArray (16);
+              memcpy (elements (laddr), &u.address6.sin6_addr, 16);
+            }
+#endif
+          else
+            throw new java::net::SocketException
+              (JvNewStringUTF ("invalid family"));
+          localAddress = new java::net::InetAddress (laddr, NULL);
+        }
+
+      return localAddress;
+      break;
+    case _Jv_IP_MULTICAST_IF_ :
+      throw new java::net::SocketException
+        (JvNewStringUTF ("IP_MULTICAST_IF: not valid for TCP"));
+      break;
+	
+    case _Jv_IP_MULTICAST_IF2_ :
+      throw new java::net::SocketException
+        (JvNewStringUTF ("IP_MULTICAST_IF2: not valid for TCP"));
+      break;
+	
+    case _Jv_IP_MULTICAST_LOOP_ :
+      throw new java::net::SocketException
+        (JvNewStringUTF ("IP_MULTICAST_LOOP: not valid for TCP"));
+      break;
+	
+    case _Jv_IP_TOS_ :
+      if (::getsockopt (fnum, SOL_SOCKET, IP_TOS, (char *) &val,
+                        &val_len) != 0)
+        goto error;
+      return new java::lang::Integer (val);
+      break;
+	
+    case _Jv_SO_REUSEADDR_ :
+      throw new java::net::SocketException
+        (JvNewStringUTF ("SO_REUSEADDR: not valid for TCP"));
+      break;
+
+    case _Jv_SO_TIMEOUT_ :
+      return new java::lang::Integer (timeout);
+      break;
+
+    default :
+      errno = ENOPROTOOPT;
+    }
+
+ error:
+  char* strerr = strerror (errno);
+  throw new java::net::SocketException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainSocketImpl::shutdownInput (void)
+{
+  if (::shutdown (fnum, 0))
+    throw new SocketException (JvNewStringUTF (strerror (errno)));
+}
+
+void
+java::net::PlainSocketImpl::shutdownOutput (void)
+{
+  if (::shutdown (fnum, 1))
+    throw new SocketException (JvNewStringUTF (strerror (errno)));
+}
+
+#endif /* DISABLE_JAVA_NET */
Index: java/net/natPlainSocketImplWin32.cc
===================================================================
RCS file: java/net/natPlainSocketImplWin32.cc
diff -N java/net/natPlainSocketImplWin32.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/net/natPlainSocketImplWin32.cc	14 Mar 2003 08:30:44 -0000
@@ -0,0 +1,1019 @@
+/* Copyright (C) 2003 Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#include <config.h>
+#include <platform.h>
+
+#ifndef DISABLE_JAVA_NET
+
+#ifdef WIN32
+
+#include <windows.h>
+#include <winsock.h>
+#include <errno.h>
+#include <string.h>
+#undef STRICT
+#undef MAX_PRIORITY
+#undef MIN_PRIORITY
+#undef FIONREAD
+
+// These functions make the Win32 socket API look more POSIXy
+static inline int
+write(int s, void *buf, int len)
+{
+  return send(s, (char*)buf, len, 0);
+}
+
+static inline int
+read(int s, void *buf, int len)
+{
+  return recv(s, (char*)buf, len, 0);
+}
+
+// these errors cannot occur on Win32
+#else /* WIN32 */
+
+#ifdef HAVE_SYS_IOCTL_H
+#define BSD_COMP /* Get FIONREAD on Solaris2. */
+#include <sys/ioctl.h>
+#endif
+
+// Pick up FIONREAD on Solaris 2.5.
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <errno.h>
+#include <string.h>
+
+#endif /* WIN32 */
+#endif /* DISABLE_JAVA_NET */
+
+#if HAVE_BSTRING_H
+// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2 
+#include <bstring.h>
+#endif
+
+
+#include <gcj/cni.h>
+#include <gcj/javaprims.h>
+#include <java/io/IOException.h>
+#include <java/io/InterruptedIOException.h>
+#include <java/net/BindException.h>
+#include <java/net/ConnectException.h>
+#include <java/net/PlainSocketImpl.h>
+#include <java/net/InetAddress.h>
+#include <java/net/InetSocketAddress.h>
+#include <java/net/SocketException.h>
+#include <java/net/SocketTimeoutException.h>
+#include <java/lang/InternalError.h>
+#include <java/lang/Object.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Class.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Thread.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalArgumentException.h>
+
+#ifdef DISABLE_JAVA_NET
+
+void
+java::net::PlainSocketImpl::create (jboolean)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("SocketImpl.create: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::bind (java::net::InetAddress *, jint)
+{
+  throw new BindException (
+    JvNewStringLatin1 ("SocketImpl.bind: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::connect (java::net::SocketAddress *, jint)
+{
+  throw new ConnectException (
+    JvNewStringLatin1 ("SocketImpl.connect: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::listen (jint)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("SocketImpl.listen: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *)
+{
+  throw new java::io::IOException (
+    JvNewStringLatin1 ("SocketImpl.accept: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::setOption (jint, java::lang::Object *)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.setOption: unimplemented"));
+}
+
+java::lang::Object *
+java::net::PlainSocketImpl::getOption (jint)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.getOption: unimplemented"));
+}
+
+jint
+java::net::PlainSocketImpl::read(void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.read: unimplemented"));
+}
+
+jint
+java::net::PlainSocketImpl::read(jbyteArray buffer, jint offset, jint count)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.read: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::write(jint b)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.write: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::write(jbyteArray b, jint offset, jint len)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.write: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::sendUrgentData(jint data)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.sendUrgentData: unimplemented"));
+}
+
+jint
+java::net::PlainSocketImpl::available(void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.available: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::close(void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.close: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::shutdownInput (void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.shutdownInput: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::shutdownOutput (void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.shutdownOutput: unimplemented"));
+}
+
+#else /* DISABLE_JAVA_NET */
+
+union SockAddr
+{
+  struct sockaddr_in address;
+#ifdef HAVE_INET6
+  struct sockaddr_in6 address6;
+#endif
+};
+
+void
+java::net::PlainSocketImpl::create (jboolean stream)
+{
+  int sock = _Jv_socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
+
+  if (sock < 0)
+    {
+      char* strerr = strerror (errno);
+      throw new java::io::IOException (JvNewStringUTF (strerr));
+    }
+
+  _Jv_platform_close_on_exec (sock);
+
+  // We use fnum in place of fd here.  From leaving fd null we avoid
+  // the double close problem in FileDescriptor.finalize.
+  fnum = sock;
+}
+
+void
+java::net::PlainSocketImpl::bind (java::net::InetAddress *host, jint lport)
+{
+  union SockAddr u;
+  struct sockaddr *ptr = (struct sockaddr *) &u.address;
+  jbyteArray haddress = host->addr;
+  jbyte *bytes = elements (haddress);
+  int len = haddress->length;
+  int i = 1;
+
+  if (len == 4)
+    {
+      u.address.sin_family = AF_INET;
+
+      if (host != NULL)
+        memcpy (&u.address.sin_addr, bytes, len);
+      else
+        u.address.sin_addr.s_addr = htonl (INADDR_ANY);
+
+      len = sizeof (struct sockaddr_in);
+      u.address.sin_port = htons (lport);
+    }
+#ifdef HAVE_INET6
+  else if (len == 16)
+    {
+      u.address6.sin6_family = AF_INET6;
+      memcpy (&u.address6.sin6_addr, bytes, len);
+      len = sizeof (struct sockaddr_in6);
+      u.address6.sin6_port = htons (lport);
+    }
+#endif
+  else
+    throw new java::net::SocketException (JvNewStringUTF ("invalid length"));
+
+  // Enable SO_REUSEADDR, so that servers can reuse ports left in TIME_WAIT.
+  ::setsockopt(fnum, SOL_SOCKET, SO_REUSEADDR, (char *) &i, sizeof(i));
+  
+  if (_Jv_bind (fnum, ptr, len) == 0)
+    {
+      address = host;
+      socklen_t addrlen = sizeof(u);
+
+      if (lport != 0)
+        localport = lport;
+      else if (::getsockname (fnum, (sockaddr*) &u, &addrlen) == 0)
+        localport = ntohs (u.address.sin_port);
+      else
+        goto error;
+
+      return;
+    }
+
+ error:
+  char* strerr = strerror (errno);
+  throw new java::net::BindException (JvNewStringUTF (strerr));
+}
+
+void
+java::net::PlainSocketImpl::connect (java::net::SocketAddress *addr,
+                                     jint timeout)
+{
+  java::net::InetSocketAddress *tmp = (java::net::InetSocketAddress*) addr;
+  java::net::InetAddress *host = tmp->getAddress();
+  jint rport = tmp->getPort();
+	
+  union SockAddr u;
+  socklen_t addrlen = sizeof(u);
+  jbyteArra