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