< prev index next >

src/java.base/windows/native/libnet/DualStackPlainSocketImpl.c

Print this page
rev 49147 : imported patch 8198358-Change-DualStackPlainSocketImpl-to-align-its-organization-with-TwoStacksPlainSocketImp-13-socketGetOption

@@ -369,37 +369,10 @@
     }
 }
 
 /*
  * Class:     java_net_DualStackPlainSocketImpl
- * Method:    localAddress
- * Signature: (ILjava/net/InetAddressContainer;)V
- */
-JNIEXPORT void JNICALL Java_java_net_DualStackPlainSocketImpl_localAddress
-  (JNIEnv *env, jclass clazz, jint fd, jobject iaContainerObj) {
-    int port;
-    SOCKETADDRESS sa;
-    int len = sizeof(sa);
-    jobject iaObj;
-    jclass iaContainerClass;
-    jfieldID iaFieldID;
-
-    if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
-        NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
-        return;
-    }
-    iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
-    CHECK_NULL(iaObj);
-
-    iaContainerClass = (*env)->GetObjectClass(env, iaContainerObj);
-    iaFieldID = (*env)->GetFieldID(env, iaContainerClass, "addr", "Ljava/net/InetAddress;");
-    CHECK_NULL(iaFieldID);
-    (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj);
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
  * Method:    socketListen
  * Signature: (I)V
  */
 JNIEXPORT void JNICALL
 Java_java_net_DualStackPlainSocketImpl_socketListen

@@ -617,48 +590,10 @@
     shutdown(fd, howto);
 }
 
 /*
  * Class:     java_net_DualStackPlainSocketImpl
- * Method:    getIntOption
- * Signature: (II)I
- */
-JNIEXPORT jint JNICALL Java_java_net_DualStackPlainSocketImpl_getIntOption
-  (JNIEnv *env, jclass clazz, jint fd, jint cmd)
-{
-    int level = 0, opt = 0;
-    int result=0;
-    struct linger linger = {0, 0};
-    char *arg;
-    int arglen;
-
-    if (NET_MapSocketOption(cmd, &level, &opt) < 0) {
-        JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
-        return -1;
-    }
-
-    if (opt == java_net_SocketOptions_SO_LINGER) {
-        arg = (char *)&linger;
-        arglen = sizeof(linger);
-    } else {
-        arg = (char *)&result;
-        arglen = sizeof(result);
-    }
-
-    if (NET_GetSockOpt(fd, level, opt, arg, &arglen) < 0) {
-        NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
-        return -1;
-    }
-
-    if (opt == java_net_SocketOptions_SO_LINGER)
-        return linger.l_onoff ? linger.l_linger : -1;
-    else
-        return result;
-}
-
-/*
- * Class:     java_net_DualStackPlainSocketImpl
  * Method:    socketNativeSetOption
  * Signature: (IZLjava/lang/Object;)V
  */
 JNIEXPORT void JNICALL
 Java_java_net_DualStackPlainSocketImpl_socketNativeSetOption

@@ -704,21 +639,21 @@
         return;
     }
 
     switch (cmd) {
 
-        case java_net_SocketOptions_TCP_NODELAY :
-        case java_net_SocketOptions_SO_OOBINLINE :
-        case java_net_SocketOptions_SO_KEEPALIVE :
-        case java_net_SocketOptions_SO_REUSEADDR :
+        case java_net_SocketOptions_TCP_NODELAY:
+        case java_net_SocketOptions_SO_OOBINLINE:
+        case java_net_SocketOptions_SO_KEEPALIVE:
+        case java_net_SocketOptions_SO_REUSEADDR:
             optval.i = (on ? 1 : 0);
             optlen = sizeof(optval.i);
             break;
 
-        case java_net_SocketOptions_SO_SNDBUF :
-        case java_net_SocketOptions_SO_RCVBUF :
-        case java_net_SocketOptions_IP_TOS :
+        case java_net_SocketOptions_SO_SNDBUF:
+        case java_net_SocketOptions_SO_RCVBUF:
+        case java_net_SocketOptions_IP_TOS:
             {
                 jclass cls;
                 jfieldID fid;
 
                 cls = (*env)->FindClass(env, "java/lang/Integer");

@@ -771,11 +706,104 @@
  */
 JNIEXPORT jint JNICALL
 Java_java_net_DualStackPlainSocketImpl_socketNativeGetOption
   (JNIEnv *env, jobject this, jint opt, jobject iaContainerObj)
 {
+    /* The fd field */
+    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
+
+    int fd;
+    int level = 0, optname = 0, optlen = 0;
+    union {
+        int i;
+        struct linger ling;
+    } optval;
+
+    /*
+     * Get SOCKET and check it hasn't been closed
+     */
+    if (IS_NULL(fdObj)) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
     return -1;
+    } else {
+        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
+    }
+    if (fd < 0) {
+        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+        return -1;
+    }
+    memset((char *)&optval, 0, sizeof(optval));
+
+    /*
+     * SO_BINDADDR isn't a socket option
+     */
+    if (opt == java_net_SocketOptions_SO_BINDADDR) {
+        SOCKETADDRESS sa;
+        int len = sizeof(sa);
+        int port;
+        jobject iaObj;
+        jclass iaContainerClass;
+        jfieldID iaFieldID;
+
+        if (getsockname(fd, &sa.sa, &len) == SOCKET_ERROR) {
+            NET_ThrowNew(env, WSAGetLastError(), "Error getting socket name");
+            return -1;
+        }
+        iaObj = NET_SockaddrToInetAddress(env, &sa, &port);
+        CHECK_NULL_RETURN(iaObj, -1);
+
+        iaContainerClass = (*env)->GetObjectClass(env, iaContainerObj);
+        iaFieldID = (*env)->GetFieldID(env, iaContainerClass, "addr", "Ljava/net/InetAddress;");
+        CHECK_NULL_RETURN(iaFieldID, -1);
+        (*env)->SetObjectField(env, iaContainerObj, iaFieldID, iaObj);
+        return 0; /* notice change from before */
+    }
+
+    /*
+     * Map the Java level socket option to the platform specific
+     * level and option name.
+     */
+    if (NET_MapSocketOption(opt, &level, &optname)) {
+        JNU_ThrowByName(env, "java/net/SocketException", "Invalid option");
+        return -1;
+    }
+
+    /*
+     * Args are int except for SO_LINGER
+     */
+    if (opt == java_net_SocketOptions_SO_LINGER) {
+        optlen = sizeof(optval.ling);
+    } else {
+        optlen = sizeof(optval.i);
+        optval.i = 0;
+    }
+
+    if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) {
+        NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
+        return -1;
+    }
+
+    switch (opt) {
+        case java_net_SocketOptions_SO_LINGER:
+            return (optval.ling.l_onoff ? optval.ling.l_linger: -1);
+
+        case java_net_SocketOptions_SO_SNDBUF:
+        case java_net_SocketOptions_SO_RCVBUF:
+        case java_net_SocketOptions_IP_TOS:
+            return optval.i;
+
+        case java_net_SocketOptions_TCP_NODELAY:
+        case java_net_SocketOptions_SO_OOBINLINE:
+        case java_net_SocketOptions_SO_KEEPALIVE:
+        case java_net_SocketOptions_SO_REUSEADDR:
+            return (optval.i == 0) ? -1 : 1;
+
+        default: /* shouldn't get here */
+            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
+                "Option not supported by TwoStacksPlainSocketImpl");
+            return -1;
+    }
 }
 
 /*
  * Class:     java_net_DualStackPlainSocketImpl
  * Method:    socketSendUrgentData
< prev index next >