summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Jones <cbj@gnu.org>2003-01-30 06:02:20 +0000
committerBrian Jones <cbj@gnu.org>2003-01-30 06:02:20 +0000
commitf4a3fd8a65ebe7203c703a2a788341a0bae6b24d (patch)
tree9b32369e2c18e29a6f8546644fa94d04d1bcbcb9
parent3cb652aadbd1bd92a672d1bc1eea7cdc6a94cf5b (diff)
downloadclasspath-f4a3fd8a65ebe7203c703a2a788341a0bae6b24d.tar.gz
* native/jni/java-net/javanet.c (_javanet_bind): following gcj's
example and setting SO_REUSEADDR before binding the port, testing with JDK seems to indicate it does this as well (_javanet_set_option): support SO_REUSEADDR; use JNI_TRUE/JNI_FALSE instead of 1/0 where applicable. Do not throw exception if setting SO_TIMEOUT fails; appears JDK does not throw exception and may be using alarm or setitimer (see `man 7 socket' on GNU/Linux) (_javanet_get_option): support SO_REUSEADDR; use JNI_TRUE/JNI_FALSE instead of 1/0 where applicable
-rw-r--r--ChangeLog12
-rw-r--r--native/jni/java-net/javanet.c47
2 files changed, 52 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 1465eed5f..f78d91650 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2003-01-30 C. Brian Jones <cbj@gnu.org>
+
+ * native/jni/java-net/javanet.c (_javanet_bind): following gcj's
+ example and setting SO_REUSEADDR before binding the port, testing
+ with JDK seems to indicate it does this as well
+ (_javanet_set_option): support SO_REUSEADDR; use JNI_TRUE/JNI_FALSE
+ instead of 1/0 where applicable. Do not throw exception if setting
+ SO_TIMEOUT fails; appears JDK does not throw exception and may be
+ using alarm or setitimer (see `man 7 socket' on GNU/Linux)
+ (_javanet_get_option): support SO_REUSEADDR; use JNI_TRUE/JNI_FALSE
+ instead of 1/0 where applicable
+
2003-01-28 Oscar Pearce <oscar@pearceenterprises.com>
* java/awt/Component.java (processPaintEvent): Dispose of Graphics
diff --git a/native/jni/java-net/javanet.c b/native/jni/java-net/javanet.c
index bf9ca957b..2db6eecbc 100644
--- a/native/jni/java-net/javanet.c
+++ b/native/jni/java-net/javanet.c
@@ -577,6 +577,10 @@ _javanet_bind(JNIEnv *env, jobject this, jobject addr, jint port, int stream)
}
DBG("_javanet_bind(): Past native_fd lookup\n");
+ _javanet_set_option (env, this, SOCKOPT_SO_REUSEADDR,
+ _javanet_create_boolean (env, JNI_TRUE));
+
+
/* Bind the socket */
memset(&si, 0, sizeof(struct sockaddr_in));
@@ -942,6 +946,7 @@ _javanet_set_option(JNIEnv *env, jobject this, jint option_id, jobject val)
break;
/* SO_TIMEOUT case. Val will be an integer with the new value */
+ /* Not writable on Linux */
case SOCKOPT_SO_TIMEOUT:
#ifdef SO_TIMEOUT
mid = (*env)->GetMethodID(env, cls, "intValue", "()I");
@@ -954,11 +959,8 @@ _javanet_set_option(JNIEnv *env, jobject this, jint option_id, jobject val)
return;
rc = setsockopt(fd, SOL_SOCKET, SO_TIMEOUT, &optval, sizeof(int));
-#else
- JCL_ThrowException(env, SOCKET_EXCEPTION,
- "SO_TIMEOUT not supported by this platform");
- return;
#endif
+ return; // ignore errors and do not throw an exception
break;
case SOCKOPT_SO_SNDBUF:
@@ -1007,6 +1009,21 @@ _javanet_set_option(JNIEnv *env, jobject this, jint option_id, jobject val)
sizeof(struct sockaddr_in));
break;
+ case SOCKOPT_SO_REUSEADDR:
+ mid = (*env)->GetMethodID(env, cls, "booleanValue", "()Z");
+ if (mid == NULL)
+ { JCL_ThrowException(env, IO_EXCEPTION,
+ "Internal error: _javanet_set_option()"); return; }
+
+ /* Should be a 0 or a 1 */
+ optval = (*env)->CallBooleanMethod(env, val, mid);
+ if ((*env)->ExceptionOccurred(env))
+ return;
+
+ rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval,
+ sizeof(int));
+ break;
+
default:
JCL_ThrowException(env, SOCKET_EXCEPTION, "Unrecognized option");
return;
@@ -1055,9 +1072,9 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id)
}
if (optval)
- return(_javanet_create_boolean(env, 1));
+ return(_javanet_create_boolean(env, JNI_TRUE));
else
- return(_javanet_create_boolean(env, 0));
+ return(_javanet_create_boolean(env, JNI_FALSE));
break;
@@ -1077,7 +1094,7 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id)
if (linger.l_onoff)
return(_javanet_create_integer(env, linger.l_linger));
else
- return(_javanet_create_boolean(env, 0));
+ return(_javanet_create_boolean(env, JNI_FALSE));
break;
@@ -1150,6 +1167,22 @@ _javanet_get_option(JNIEnv *env, jobject this, jint option_id)
return(_javanet_create_inetaddress(env, ntohl(si.sin_addr.s_addr)));
break;
+ case SOCKOPT_SO_REUSEADDR:
+ optlen = sizeof(int);
+ rc = getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, &optlen);
+ if (rc == -1)
+ {
+ JCL_ThrowException(env, SOCKET_EXCEPTION, strerror(errno));
+ return(0);
+ }
+
+ if (optval)
+ return(_javanet_create_boolean(env, JNI_TRUE));
+ else
+ return(_javanet_create_boolean(env, JNI_FALSE));
+
+ break;
+
default:
JCL_ThrowException(env, SOCKET_EXCEPTION, "No such option" );
return(0);