Hi there,

in javanet.c we fiddle with the fd and localport fields in
java.net.SocketImpl. However, if we do DatagramSocket stuff, javanet.c
still tries to play with SocketImpl, although it should be
DatagramSocketImpl. Surprisingly, this often works, because the field
order is the same for both classes. However, if somebody has the idea to
change this, we will segfault. Also, in VMs that play with the field
order (like Jamaica), this can also segfault. To make things worse, Sun
decided to name the field localport -> localPort in DatagramSocketImpl.
This patch fixes all these problems by special casing stream vs datagram
sockets in javanet.c.

2006-01-09  Roman Kennke  <[EMAIL PROTECTED]>

        * native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c
        (connect): Added stream parameter to _connect() call.
        * native/jni/java-net/gnu_java_net_VMPlainDatagramSocketImpl.c
        (connect): Added stream parameter to _connect() call.
        * native/jni/java-net/javanet.c
        (_javanet_create_localfd): Added stream parameter. Look up
        fd field based on the stream parameter either in SocketImpl or
        in DatagramSocketImpl.
        (_javanet_connect): Added stream parameter. Call create_localfd
        using this stream parameter. Set localPort field either in
        SocketImpl or in DatagramSocketImpl, depending on the stream
        flag.
        * native/jni/java-net/javanet.c
        (_javanet_connect): Added stream parameter.

/Roman
Index: native/jni/java-net/gnu_java_net_VMPlainDatagramSocketImpl.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/java-net/gnu_java_net_VMPlainDatagramSocketImpl.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_java_net_VMPlainDatagramSocketImpl.c
--- native/jni/java-net/gnu_java_net_VMPlainDatagramSocketImpl.c	4 Jan 2006 21:22:08 -0000	1.2
+++ native/jni/java-net/gnu_java_net_VMPlainDatagramSocketImpl.c	9 Jan 2006 21:12:57 -0000
@@ -115,7 +115,7 @@
   assert(env!=NULL);
   assert((*env)!=NULL);
 
-  _javanet_connect(env, obj, addr, port);
+  _javanet_connect(env, obj, addr, port, 0);
 #else /* not WITHOUT_NETWORK */
 #endif /* not WITHOUT_NETWORK */
 }
Index: native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_java_net_VMPlainSocketImpl.c
--- native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c	4 Jan 2006 21:22:08 -0000	1.2
+++ native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c	9 Jan 2006 21:12:57 -0000
@@ -116,7 +116,7 @@
   assert(env!=NULL);
   assert((*env)!=NULL);
 
-  _javanet_connect(env, obj, addr, port);
+  _javanet_connect(env, obj, addr, port, 1);
 #else /* not WITHOUT_NETWORK */
 #endif /* not WITHOUT_NETWORK */
 }
Index: native/jni/java-net/javanet.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/java-net/javanet.c,v
retrieving revision 1.25
diff -u -r1.25 javanet.c
--- native/jni/java-net/javanet.c	20 Sep 2005 12:17:16 -0000	1.25
+++ native/jni/java-net/javanet.c	9 Jan 2006 21:12:58 -0000
@@ -133,7 +133,7 @@
  * need to include it.
  */
 static void
-_javanet_create_localfd (JNIEnv * env, jobject this)
+_javanet_create_localfd (JNIEnv * env, jobject this, jboolean stream)
 {
   jclass this_cls, fd_cls;
   jfieldID fid;
@@ -146,7 +146,10 @@
   DBG ("_javanet_create_localfd(): Entered _javanet_create_localfd\n");
 
   /* Look up the fd field */
-  this_cls = (*env)->FindClass (env, "java/net/SocketImpl");
+  if (stream)
+    this_cls = (*env)->FindClass(env, "java/net/SocketImpl");
+  else
+    this_cls = (*env)->FindClass(env, "java/net/DatagramSocketImpl");
   if (this_cls == NULL)
     return;
 
@@ -552,7 +555,8 @@
  * Connects to the specified destination.
  */
 void
-_javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port)
+_javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port,
+		  jboolean stream)
 {
 #ifndef WITHOUT_NETWORK
   int netaddr, fd;
@@ -613,7 +617,7 @@
       return;
     }
 
-  _javanet_create_localfd (env, this);
+  _javanet_create_localfd (env, this, stream);
   if ((*env)->ExceptionOccurred (env))
     {
       /* We don't care whether this succeeds. close() will cleanup later. */
@@ -622,8 +626,13 @@
     }
   DBG ("_javanet_connect(): Created fd\n");
 
-  _javanet_set_int_field (env, this, "java/net/SocketImpl", "localport",
-			  local_port);
+  if (stream)
+    _javanet_set_int_field (env, this, "java/net/SocketImpl", "localport",
+			    local_port);
+  else
+    _javanet_set_int_field (env, this, "java/net/DatagramSocketImpl",
+			    "localPort", local_port);
+
   if ((*env)->ExceptionOccurred (env))
     {
       /* We don't care whether this succeeds. close() will cleanup later. */
@@ -643,31 +652,36 @@
       return;
     }
 
-  if (remote_address == netaddr)
-    {
-      _javanet_set_remhost_addr (env, this, addr);
-    }
-  else
-    {
-      _javanet_set_remhost (env, this, remote_address);
-    }
-  if ((*env)->ExceptionOccurred (env))
+  if (stream)
     {
-      /* We don't care whether this succeeds. close() will cleanup later. */
-      TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
-      return;
-    }
-  DBG ("_javanet_connect(): Set the remote host\n");
+      if (remote_address == netaddr)
+	{
+	  _javanet_set_remhost_addr (env, this, addr);
+	}
+      else
+	{
+	  _javanet_set_remhost (env, this, remote_address);
+	}
+      if ((*env)->ExceptionOccurred (env))
+	{
+	  /* We don't care whether this succeeds. close() will cleanup later.
+	   */
+	  TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+	  return;
+	}
+      DBG ("_javanet_connect(): Set the remote host\n");
 
-  _javanet_set_int_field (env, this, "java/net/SocketImpl", "port",
-			  remote_port);
-  if ((*env)->ExceptionOccurred (env))
-    {
-      /* We don't care whether this succeeds. close() will cleanup later. */
-      TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
-      return;
+      _javanet_set_int_field (env, this, "java/net/SocketImpl", "port",
+			      remote_port);
+      if ((*env)->ExceptionOccurred (env))
+	{
+	  /* We don't care whether this succeeds. close() will cleanup later.
+	   */
+	  TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result);
+	  return;
+	}
+      DBG ("_javanet_connect(): Set the remote port\n");
     }
-  DBG ("_javanet_connect(): Set the remote port\n");
 #else /* not WITHOUT_NETWORK */
 #endif /* not WITHOUT_NETWORK */
 }
@@ -897,7 +911,7 @@
       return;
     }
 
-  _javanet_create_localfd (env, impl);
+  _javanet_create_localfd (env, impl, 1);
   if ((*env)->ExceptionOccurred (env))
     {
       /* We don't care whether this succeeds. close() will cleanup later. */
Index: native/jni/java-net/javanet.h
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/java-net/javanet.h,v
retrieving revision 1.9
diff -u -r1.9 javanet.h
--- native/jni/java-net/javanet.h	2 Jul 2005 20:32:55 -0000	1.9
+++ native/jni/java-net/javanet.h	9 Jan 2006 21:12:58 -0000
@@ -92,7 +92,7 @@
 extern int _javanet_get_netaddr(JNIEnv *, jobject);
 extern void _javanet_create(JNIEnv *, jobject, jboolean);
 extern void _javanet_close(JNIEnv *, jobject, int);
-extern void _javanet_connect(JNIEnv *, jobject, jobject, jint);
+extern void _javanet_connect(JNIEnv *, jobject, jobject, jint, jboolean);
 extern void _javanet_bind(JNIEnv *, jobject, jobject, jint, int);
 extern void _javanet_listen(JNIEnv *, jobject, jint);
 extern void _javanet_accept(JNIEnv *, jobject, jobject);
_______________________________________________
Classpath-patches mailing list
Classpath-patches@gnu.org
http://lists.gnu.org/mailman/listinfo/classpath-patches

Reply via email to