diff options
Diffstat (limited to 'native/jni/java-net')
-rw-r--r-- | native/jni/java-net/gnu_java_net_PlainDatagramSocketImpl.c | 76 | ||||
-rw-r--r-- | native/jni/java-net/gnu_java_net_PlainSocketImpl.c | 4 | ||||
-rw-r--r-- | native/jni/java-net/java_net_VMInetAddress.c | 4 | ||||
-rw-r--r-- | native/jni/java-net/java_net_VMNetworkInterface.c | 4 | ||||
-rw-r--r-- | native/jni/java-net/javanet.c | 168 | ||||
-rw-r--r-- | native/jni/java-net/javanet.h | 4 |
6 files changed, 155 insertions, 105 deletions
diff --git a/native/jni/java-net/gnu_java_net_PlainDatagramSocketImpl.c b/native/jni/java-net/gnu_java_net_PlainDatagramSocketImpl.c index a02cdeb1c..5bc284f64 100644 --- a/native/jni/java-net/gnu_java_net_PlainDatagramSocketImpl.c +++ b/native/jni/java-net/gnu_java_net_PlainDatagramSocketImpl.c @@ -15,8 +15,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and @@ -207,7 +207,9 @@ Java_gnu_java_net_PlainDatagramSocketImpl_receive0 (JNIEnv * env, jobject obj, } arr = (*env)->CallObjectMethod (env, packet, mid); - if ((arr == NULL) || (*env)->ExceptionOccurred (env)) + if ((*env)->ExceptionOccurred (env)) + return; + if (arr == NULL) { JCL_ThrowException (env, IO_EXCEPTION, "Internal error: call getData"); return; @@ -223,11 +225,7 @@ Java_gnu_java_net_PlainDatagramSocketImpl_receive0 (JNIEnv * env, jobject obj, offset = (*env)->CallIntMethod (env, packet, mid); if ((*env)->ExceptionOccurred (env)) - { - JCL_ThrowException (env, IO_EXCEPTION, - "Internal error: call getOffset"); - return; - } + return; DBG ("PlainDatagramSocketImpl.receive(): Got the offset\n"); @@ -241,16 +239,15 @@ Java_gnu_java_net_PlainDatagramSocketImpl_receive0 (JNIEnv * env, jobject obj, maxlen = (*env)->GetIntField (env, packet, fid); if ((*env)->ExceptionOccurred (env)) - { - JCL_ThrowException (env, IO_EXCEPTION, "Internal error: call length"); - return; - } + return; /* Receive the packet */ /* should we try some sort of validation on the length? */ bytes_read = _javanet_recvfrom (env, obj, arr, offset, maxlen, &addr, &port); - if ((bytes_read == -1) || (*env)->ExceptionOccurred (env)) + if ((*env)->ExceptionOccurred (env)) + return; + if (bytes_read == -1) { JCL_ThrowException (env, IO_EXCEPTION, "Internal error: receive"); return; @@ -292,11 +289,7 @@ Java_gnu_java_net_PlainDatagramSocketImpl_receive0 (JNIEnv * env, jobject obj, addr_obj = (*env)->CallStaticObjectMethod (env, addr_cls, mid, ip_str_obj); if ((*env)->ExceptionOccurred (env)) - { - JCL_ThrowException (env, IO_EXCEPTION, - "Internal error: call getByName"); - return; - } + return; mid = (*env)->GetMethodID (env, cls, "setAddress", "(Ljava/net/InetAddress;)V"); @@ -308,11 +301,7 @@ Java_gnu_java_net_PlainDatagramSocketImpl_receive0 (JNIEnv * env, jobject obj, (*env)->CallVoidMethod (env, packet, mid, addr_obj); if ((*env)->ExceptionOccurred (env)) - { - JCL_ThrowException (env, IO_EXCEPTION, - "Internal error: call setAddress"); - return; - } + return; DBG ("PlainDatagramSocketImpl.receive(): Stored the address\n"); @@ -326,10 +315,7 @@ Java_gnu_java_net_PlainDatagramSocketImpl_receive0 (JNIEnv * env, jobject obj, (*env)->CallVoidMethod (env, packet, mid, port); if ((*env)->ExceptionOccurred (env)) - { - JCL_ThrowException (env, IO_EXCEPTION, "Internal error: call setPort"); - return; - } + return; DBG ("PlainDatagramSocketImpl.receive(): Stored the port\n"); @@ -343,10 +329,7 @@ Java_gnu_java_net_PlainDatagramSocketImpl_receive0 (JNIEnv * env, jobject obj, (*env)->SetIntField (env, packet, fid, bytes_read); if ((*env)->ExceptionOccurred (env)) - { - JCL_ThrowException (env, IO_EXCEPTION, "Internal error: call length"); - return; - } + return; DBG ("PlainDatagramSocketImpl.receive(): Stored the length\n"); #else /* not WITHOUT_NETWORK */ @@ -372,20 +355,13 @@ Java_gnu_java_net_PlainDatagramSocketImpl_sendto (JNIEnv * env, jobject obj, netAddress = _javanet_get_netaddr (env, addr); if ((*env)->ExceptionOccurred (env)) - { - JCL_ThrowException (env, IO_EXCEPTION, - "Internal error: get network address"); - return; - } + return; DBG ("PlainDatagramSocketImpl.sendto(): have addr\n"); _javanet_sendto (env, obj, buf, offset, len, netAddress, port); if ((*env)->ExceptionOccurred (env)) - { - JCL_ThrowException (env, IO_EXCEPTION, "Internal error: send data"); - return; - } + return; DBG ("PlainDatagramSocketImpl.sendto(): finished\n"); #else /* not WITHOUT_NETWORK */ @@ -411,17 +387,11 @@ Java_gnu_java_net_PlainDatagramSocketImpl_join (JNIEnv * env, jobject obj, netAddress = _javanet_get_netaddr (env, addr); if ((*env)->ExceptionOccurred (env)) - { - JCL_ThrowException (env, IO_EXCEPTION, "Internal error"); - return; - } + return; fd = _javanet_get_int_field (env, obj, "native_fd"); if ((*env)->ExceptionOccurred (env)) - { - JCL_ThrowException (env, IO_EXCEPTION, "Internal error"); - return; - } + return; DBG ("PlainDatagramSocketImpl.join(): have native fd\n"); @@ -459,17 +429,11 @@ Java_gnu_java_net_PlainDatagramSocketImpl_leave (JNIEnv * env, jobject obj, netAddress = _javanet_get_netaddr (env, addr); if ((*env)->ExceptionOccurred (env)) - { - JCL_ThrowException (env, IO_EXCEPTION, "Internal error"); - return; - } + return; fd = _javanet_get_int_field (env, obj, "native_fd"); if ((*env)->ExceptionOccurred (env)) - { - JCL_ThrowException (env, IO_EXCEPTION, "Internal error"); - return; - } + return; DBG ("PlainDatagramSocketImpl.leave(): have native fd\n"); diff --git a/native/jni/java-net/gnu_java_net_PlainSocketImpl.c b/native/jni/java-net/gnu_java_net_PlainSocketImpl.c index 086aeded3..a5261514d 100644 --- a/native/jni/java-net/gnu_java_net_PlainSocketImpl.c +++ b/native/jni/java-net/gnu_java_net_PlainSocketImpl.c @@ -15,8 +15,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and diff --git a/native/jni/java-net/java_net_VMInetAddress.c b/native/jni/java-net/java_net_VMInetAddress.c index 6247a70ba..d33265cff 100644 --- a/native/jni/java-net/java_net_VMInetAddress.c +++ b/native/jni/java-net/java_net_VMInetAddress.c @@ -15,8 +15,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and diff --git a/native/jni/java-net/java_net_VMNetworkInterface.c b/native/jni/java-net/java_net_VMNetworkInterface.c index 47ea150b2..71f5e8927 100644 --- a/native/jni/java-net/java_net_VMNetworkInterface.c +++ b/native/jni/java-net/java_net_VMNetworkInterface.c @@ -15,8 +15,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and diff --git a/native/jni/java-net/javanet.c b/native/jni/java-net/javanet.c index f778af66f..fdc1c22ec 100644 --- a/native/jni/java-net/javanet.c +++ b/native/jni/java-net/javanet.c @@ -15,8 +15,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and @@ -377,6 +377,13 @@ _javanet_get_netaddr (JNIEnv * env, jobject addr) DBG ("_javanet_get_netaddr(): Entered _javanet_get_netaddr\n"); + if (addr == NULL) + { + JCL_ThrowException (env, "java/lang/NullPointerException", + "Null address"); + return 0; + } + /* Call the getAddress method on the object to retrieve the IP address */ cls = (*env)->GetObjectClass (env, addr); if (cls == NULL) @@ -473,6 +480,22 @@ _javanet_create (JNIEnv * env, jobject this, jboolean stream) else _javanet_set_int_field (env, this, "gnu/java/net/PlainDatagramSocketImpl", "native_fd", fd); + + if ((*env)->ExceptionOccurred (env)) + { + /* Try to make sure we close the socket since close() won't work. */ + do + { + TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); + if (result != TARGET_NATIVE_OK + && (TARGET_NATIVE_LAST_ERROR () + != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)) + return; + } + while (result != TARGET_NATIVE_OK); + return; + } + #else /* not WITHOUT_NETWORK */ #endif /* not WITHOUT_NETWORK */ } @@ -489,6 +512,7 @@ _javanet_close (JNIEnv * env, jobject this, int stream) #ifndef WITHOUT_NETWORK int fd; int result; + int error = 0; assert (env != NULL); assert ((*env) != NULL); @@ -497,14 +521,27 @@ _javanet_close (JNIEnv * env, jobject this, int stream) if (fd == -1) return; - TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); - if (stream) _javanet_set_int_field (env, this, "gnu/java/net/PlainSocketImpl", "native_fd", -1); else _javanet_set_int_field (env, this, "gnu/java/net/PlainDatagramSocketImpl", "native_fd", -1); + do + { + TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); + if (result != TARGET_NATIVE_OK) + { + /* Only throw an error when a "real" error occurs. */ + error = TARGET_NATIVE_LAST_ERROR (); + if (error != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL + && error != ENOTCONN && error != ECONNRESET && error != EBADF) + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + } + } + while (error == TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL); + #else /* not WITHOUT_NETWORK */ #endif /* not WITHOUT_NETWORK */ } @@ -548,13 +585,20 @@ _javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port) DBG ("_javanet_connect(): Got native fd\n"); /* Connect up */ - TARGET_NATIVE_NETWORK_SOCKET_CONNECT (fd, netaddr, port, result); - if (result != TARGET_NATIVE_OK) + do { - JCL_ThrowException (env, IO_EXCEPTION, - TARGET_NATIVE_LAST_ERROR_STRING ()); - return; + TARGET_NATIVE_NETWORK_SOCKET_CONNECT (fd, netaddr, port, result); + if (result != TARGET_NATIVE_OK + && (TARGET_NATIVE_LAST_ERROR () + != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + return; + } } + while (result != TARGET_NATIVE_OK); + DBG ("_javanet_connect(): Connected successfully\n"); /* Populate instance variables */ @@ -562,15 +606,17 @@ _javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port) result); if (result != TARGET_NATIVE_OK) { - TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); + /* We don't care whether this succeeds. close() will cleanup later. */ + TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); return; } _javanet_create_localfd (env, this); if ((*env)->ExceptionOccurred (env)) { + /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); return; } @@ -580,6 +626,7 @@ _javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port) local_port); if ((*env)->ExceptionOccurred (env)) { + /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); return; } @@ -589,9 +636,10 @@ _javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port) remote_port, result); if (result != TARGET_NATIVE_OK) { - TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); + /* We don't care whether this succeeds. close() will cleanup later. */ + TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); return; } @@ -605,6 +653,7 @@ _javanet_connect (JNIEnv * env, jobject this, jobject addr, jint port) } if ((*env)->ExceptionOccurred (env)) { + /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (fd, result); return; } @@ -614,6 +663,7 @@ _javanet_connect (JNIEnv * env, jobject this, jobject addr, jint 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; } @@ -698,16 +748,19 @@ _javanet_bind (JNIEnv * env, jobject this, jobject addr, jint port, octets[3], tmpaddr); TARGET_NATIVE_NETWORK_SOCKET_BIND (fd, tmpaddr, port, result); - (*env)->ReleaseByteArrayElements (env, arr, octets, 0); - if (result != TARGET_NATIVE_OK) { + char *errorstr = TARGET_NATIVE_LAST_ERROR_STRING (); + (*env)->ReleaseByteArrayElements (env, arr, octets, 0); + JCL_ThrowException (env, BIND_EXCEPTION, - TARGET_NATIVE_LAST_ERROR_STRING ()); + errorstr); return; } DBG ("_javanet_bind(): Past bind\n"); + (*env)->ReleaseByteArrayElements (env, arr, octets, 0); + /* Update instance variables, specifically the local port number */ TARGET_NATIVE_NETWORK_SOCKET_GET_LOCAL_INFO (fd, local_address, local_port, result); @@ -816,7 +869,16 @@ _javanet_accept (JNIEnv * env, jobject this, jobject impl) if ((*env)->ExceptionOccurred (env)) { - TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); + /* Try to make sure we close the socket since close() won't work. */ + do + { + TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); + if (result != TARGET_NATIVE_OK + && (TARGET_NATIVE_LAST_ERROR () + != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)) + return; + } + while (result != TARGET_NATIVE_OK); return; } @@ -824,6 +886,7 @@ _javanet_accept (JNIEnv * env, jobject this, jobject impl) local_port, result); if (result != TARGET_NATIVE_OK) { + /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); @@ -833,6 +896,7 @@ _javanet_accept (JNIEnv * env, jobject this, jobject impl) _javanet_create_localfd (env, impl); if ((*env)->ExceptionOccurred (env)) { + /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); return; } @@ -841,6 +905,7 @@ _javanet_accept (JNIEnv * env, jobject this, jobject impl) local_port); if ((*env)->ExceptionOccurred (env)) { + /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); return; } @@ -849,15 +914,17 @@ _javanet_accept (JNIEnv * env, jobject this, jobject impl) remote_port, result); if (result != TARGET_NATIVE_OK) { - TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); JCL_ThrowException (env, IO_EXCEPTION, TARGET_NATIVE_LAST_ERROR_STRING ()); + /* We don't care whether this succeeds. close() will cleanup later. */ + TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); return; } _javanet_set_remhost (env, impl, remote_address); if ((*env)->ExceptionOccurred (env)) { + /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); return; } @@ -866,6 +933,7 @@ _javanet_accept (JNIEnv * env, jobject this, jobject impl) remote_port); if ((*env)->ExceptionOccurred (env)) { + /* We don't care whether this succeeds. close() will cleanup later. */ TARGET_NATIVE_NETWORK_SOCKET_CLOSE (newfd, result); return; } @@ -945,15 +1013,21 @@ _javanet_recvfrom (JNIEnv * env, jobject this, jarray buf, int offset, (TARGET_NATIVE_LAST_ERROR () == TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL)); - (*env)->ReleaseByteArrayElements (env, buf, p, 0); - if (received_bytes == -1) { - JCL_ThrowException (env, IO_EXCEPTION, - TARGET_NATIVE_LAST_ERROR_STRING ()); + if (TARGET_NATIVE_LAST_ERROR () == EAGAIN) + JCL_ThrowException (env, "java/net/SocketTimeoutException", "Timeout"); + else + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + + /* Cleanup and return. */ + (*env)->ReleaseByteArrayElements (env, buf, p, 0); return 0; } + (*env)->ReleaseByteArrayElements (env, buf, p, 0); + /* Handle return addr case */ if (addr != NULL) { @@ -1004,29 +1078,42 @@ _javanet_sendto (JNIEnv * env, jobject this, jarray buf, int offset, int len, if (p == NULL) return; - /* Send the data */ - if (addr == 0) + /* We must send all the data, so repeat till done. */ + while (len > 0) { - DBG ("_javanet_sendto(): Sending....\n"); - TARGET_NATIVE_NETWORK_SOCKET_SEND (fd, p + offset, len, bytes_sent); - } - else - { - DBG ("_javanet_sendto(): Sending....\n"); - TARGET_NATIVE_NETWORK_SOCKET_SEND_WITH_ADDRESS_PORT (fd, p + offset, - len, addr, port, - bytes_sent); + /* Send the data */ + if (addr == 0) + { + DBG ("_javanet_sendto(): Sending....\n"); + TARGET_NATIVE_NETWORK_SOCKET_SEND (fd, p + offset, len, bytes_sent); + } + else + { + DBG ("_javanet_sendto(): Sending....\n"); + TARGET_NATIVE_NETWORK_SOCKET_SEND_WITH_ADDRESS_PORT (fd, p + offset, + len, addr, port, + bytes_sent); + } + + if (bytes_sent < 0) + { + if (TARGET_NATIVE_LAST_ERROR () + != TARGET_NATIVE_ERROR_INTERRUPT_FUNCTION_CALL) + { + JCL_ThrowException (env, IO_EXCEPTION, + TARGET_NATIVE_LAST_ERROR_STRING ()); + break; + } + } + else + { + len -= bytes_sent; + addr += bytes_sent; + } } (*env)->ReleaseByteArrayElements (env, buf, p, 0); - /***** Do we need to check EINTR? */ - if (bytes_sent < 0) - { - JCL_ThrowException (env, IO_EXCEPTION, - TARGET_NATIVE_LAST_ERROR_STRING ()); - return; - } #else /* not WITHOUT_NETWORK */ #endif /* not WITHOUT_NETWORK */ } @@ -1139,9 +1226,9 @@ _javanet_set_option (JNIEnv * env, jobject this, jint option_id, jobject val) return; TARGET_NATIVE_NETWORK_SOCKET_SET_OPTION_SO_TIMEOUT (fd, optval, result); -#endif - /* ignore errors and do not throw an exception. */ +#else result = TARGET_NATIVE_OK; +#endif break; case SOCKOPT_SO_SNDBUF: @@ -1326,7 +1413,6 @@ _javanet_get_option (JNIEnv * env, jobject this, jint option_id) TARGET_NATIVE_LAST_ERROR_STRING ()); return (0); } - return (_javanet_create_integer (env, optval)); #else JCL_ThrowException (env, SOCKET_EXCEPTION, diff --git a/native/jni/java-net/javanet.h b/native/jni/java-net/javanet.h index dc28bbf60..7c77ea77f 100644 --- a/native/jni/java-net/javanet.h +++ b/native/jni/java-net/javanet.h @@ -15,8 +15,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and |