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]

Patch: FYI: PR 28576


I'm checking this in on the trunk.

This fixes PR 28576 by implementing connect() and disconnect() for
datagram sockets.  It also fixes send() to work in the case where the
socket is connected and the packet has no address.

I tested this before and after using dnsjava (which is a nice package
btw).

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	PR libgcj/28576:
	* gnu/java/net/natPlainDatagramSocketImplPosix.cc (connect):
	Implemented.
	(disconnect): Likewise.
	(send): Handle already-connected case.

Index: gnu/java/net/natPlainDatagramSocketImplPosix.cc
===================================================================
--- gnu/java/net/natPlainDatagramSocketImplPosix.cc	(revision 115941)
+++ gnu/java/net/natPlainDatagramSocketImplPosix.cc	(working copy)
@@ -39,6 +39,8 @@
 #include <java/lang/Boolean.h>
 #include <java/lang/Integer.h>
 #include <java/net/UnknownHostException.h>
+#include <java/net/ConnectException.h>
+#include <java/lang/NullPointerException.h>
 
 union SockAddr
 {
@@ -149,17 +151,49 @@
 }
 
 void
-gnu::java::net::PlainDatagramSocketImpl::connect (::java::net::InetAddress *, jint)
+gnu::java::net::PlainDatagramSocketImpl::connect (::java::net::InetAddress *host,
+						  jint rport)
 { 
-  throw new ::java::lang::InternalError (JvNewStringLatin1 (
-	    "PlainDatagramSocketImpl::connect: not implemented yet"));
+  if (! host)
+    throw new ::java::lang::NullPointerException;
+
+  union SockAddr 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 (_Jv_connect (native_fd, ptr, len) == 0)
+    return;
+  char* strerr = strerror (errno);
+  throw new ::java::net::ConnectException (JvNewStringUTF (strerr));
 }
 
 void
 gnu::java::net::PlainDatagramSocketImpl::disconnect ()
 {
-  throw new ::java::lang::InternalError (JvNewStringLatin1 (
-	    "PlainDatagramSocketImpl::disconnect: not implemented yet"));
+  struct sockaddr addr;
+  addr.sa_family = AF_UNSPEC;
+  // Ignore errors.  This is lame but apparently required.
+  _Jv_connect (native_fd, &addr, sizeof (addr));
 }
 
 jint
@@ -289,39 +323,50 @@
 {
   JvSynchronize lock (SEND_LOCK);
   
-  // FIXME: Deal with Multicast and if the socket is connected.
-  jint rport = p->getPort();
-  union SockAddr u;
+  // FIXME: Deal with Multicast.
+
   ::java::net::InetAddress *host = p->getAddress();
-  if (! host)
-    throw new ::java::net::UnknownHostException(p->toString());
-
-  jbyteArray haddress = host->addr;
-  jbyte *bytes = elements (haddress);
-  int len = haddress->length;
-  struct sockaddr *ptr = (struct sockaddr *) &u.address;
-  jbyte *dbytes = elements (p->getData()) + p->getOffset();
-  if (len == 4)
+  if (host == NULL)
     {
-      u.address.sin_family = AF_INET;
-      memcpy (&u.address.sin_addr, bytes, len);
-      len = sizeof (struct sockaddr_in);
-      u.address.sin_port = htons (rport);
+      // If there is no host, maybe this socket was connected, in
+      // which case we try a plain send().
+      jbyte *dbytes = elements (p->getData()) + p->getOffset();
+      if (::send (native_fd, (char *) dbytes, p->getLength(), 0) >= 0)
+	return;
     }
+  else
+    {
+      jint rport = p->getPort();
+      union SockAddr u;
+
+      jbyteArray haddress = host->addr;
+      jbyte *bytes = elements (haddress);
+      int len = haddress->length;
+      struct sockaddr *ptr = (struct sockaddr *) &u.address;
+      jbyte *dbytes = elements (p->getData()) + p->getOffset();
+      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);
-    }
+      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"));
+      else
+	throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
 
-  if (::sendto (native_fd, (char *) dbytes, p->getLength(), 0, ptr, len) >= 0)
-    return;
+      if (::sendto (native_fd, (char *) dbytes, p->getLength(), 0, ptr, len)
+	  >= 0)
+	return;
+    }
 
   char* strerr = strerror (errno);
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]