jdk/src/solaris/native/sun/nio/ch/Net.c
changeset 12047 320a714614e9
parent 9035 1255eb81cc2f
child 13363 065e0e3545a3
--- a/jdk/src/solaris/native/sun/nio/ch/Net.c	Tue Mar 06 10:25:45 2012 +0800
+++ b/jdk/src/solaris/native/sun/nio/ch/Net.c	Tue Mar 06 20:34:38 2012 +0000
@@ -116,6 +116,47 @@
 
 #endif   /* __linux__ */
 
+#ifdef _ALLBSD_SOURCE
+
+#ifndef IP_BLOCK_SOURCE
+
+#define IP_ADD_SOURCE_MEMBERSHIP        70   /* join a source-specific group */
+#define IP_DROP_SOURCE_MEMBERSHIP       71   /* drop a single source */
+#define IP_BLOCK_SOURCE                 72   /* block a source */
+#define IP_UNBLOCK_SOURCE               73   /* unblock a source */
+
+#endif  /* IP_BLOCK_SOURCE */
+
+#ifndef MCAST_BLOCK_SOURCE
+
+#define MCAST_JOIN_SOURCE_GROUP         82   /* join a source-specific group */
+#define MCAST_LEAVE_SOURCE_GROUP        83   /* leave a single source */
+#define MCAST_BLOCK_SOURCE              84   /* block a source */
+#define MCAST_UNBLOCK_SOURCE            85   /* unblock a source */
+
+#endif /* MCAST_BLOCK_SOURCE */
+
+#ifndef IPV6_ADD_MEMBERSHIP
+
+#define IPV6_ADD_MEMBERSHIP     IPV6_JOIN_GROUP
+#define IPV6_DROP_MEMBERSHIP    IPV6_LEAVE_GROUP
+
+#endif /* IPV6_ADD_MEMBERSHIP */
+
+struct my_ip_mreq_source {
+        struct in_addr  imr_multiaddr;
+        struct in_addr  imr_interface;
+        struct in_addr  imr_sourceaddr;
+};
+
+struct my_group_source_req {
+        uint32_t                gsr_interface;  /* interface index */
+        struct sockaddr_storage gsr_group;      /* group address */
+        struct sockaddr_storage gsr_source;     /* source address */
+};
+
+#endif   /* _ALLBSD_SOURCE */
+
 
 #define COPY_INET6_ADDRESS(env, source, target) \
     (*env)->GetByteArrayRegion(env, source, 0, 16, target)
@@ -157,7 +198,12 @@
 JNIEXPORT jboolean JNICALL
 Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0(JNIEnv* env, jclass cl)
 {
+#ifdef MACOSX
+    /* for now IPv6 sockets cannot join IPv4 multicast groups */
+    return JNI_FALSE;
+#else
     return JNI_TRUE;
+#endif
 }
 
 JNIEXPORT jboolean JNICALL
@@ -287,8 +333,30 @@
     SOCKADDR sa;
     socklen_t sa_len = SOCKADDR_LEN;
     if (getsockname(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) < 0) {
+#ifdef _ALLBSD_SOURCE
+        /*
+         * XXXBSD:
+         * ECONNRESET is specific to the BSDs. We can not return an error,
+         * as the calling Java code with raise a java.lang.Error given the expectation
+         * that getsockname() will never fail. According to the Single UNIX Specification,
+         * it shouldn't fail. As such, we just fill in generic Linux-compatible values.
+         */
+        if (errno == ECONNRESET) {
+            struct sockaddr_in *sin;
+            sin = (struct sockaddr_in *) &sa;
+            bzero(sin, sizeof(*sin));
+            sin->sin_len  = sizeof(struct sockaddr_in);
+            sin->sin_family = AF_INET;
+            sin->sin_port = htonl(0);
+            sin->sin_addr.s_addr = INADDR_ANY;
+        } else {
+            handleSocketError(env, errno);
+            return -1;
+        }
+#else /* _ALLBSD_SOURCE */
         handleSocketError(env, errno);
         return -1;
+#endif /* _ALLBSD_SOURCE */
     }
     return NET_GetPortFromSockaddr((struct sockaddr *)&sa);
 }
@@ -300,8 +368,30 @@
     socklen_t sa_len = SOCKADDR_LEN;
     int port;
     if (getsockname(fdval(env, fdo), (struct sockaddr *)&sa, &sa_len) < 0) {
+#ifdef _ALLBSD_SOURCE
+        /*
+         * XXXBSD:
+         * ECONNRESET is specific to the BSDs. We can not return an error,
+         * as the calling Java code with raise a java.lang.Error with the expectation
+         * that getsockname() will never fail. According to the Single UNIX Specification,
+         * it shouldn't fail. As such, we just fill in generic Linux-compatible values.
+         */
+        if (errno == ECONNRESET) {
+            struct sockaddr_in *sin;
+            sin = (struct sockaddr_in *) &sa;
+            bzero(sin, sizeof(*sin));
+            sin->sin_len  = sizeof(struct sockaddr_in);
+            sin->sin_family = AF_INET;
+            sin->sin_port = htonl(0);
+            sin->sin_addr.s_addr = INADDR_ANY;
+        } else {
+            handleSocketError(env, errno);
+            return NULL;
+        }
+#else /* _ALLBSD_SOURCE */
         handleSocketError(env, errno);
         return NULL;
+#endif /* _ALLBSD_SOURCE */
     }
     return NET_SockaddrToInetAddress(env, (struct sockaddr *)&sa, &port);
 }
@@ -365,7 +455,8 @@
     struct linger linger;
     u_char carg;
     void *parg;
-    int arglen, n;
+    socklen_t arglen;
+    int n;
 
     /* Option value is an int except for a few specific cases */
 
@@ -419,12 +510,17 @@
         optval = (void*)&mreq;
         optlen = sizeof(mreq);
     } else {
+#ifdef MACOSX
+        /* no IPv4 include-mode filtering for now */
+        return IOS_UNAVAILABLE;
+#else
         mreq_source.imr_multiaddr.s_addr = htonl(group);
         mreq_source.imr_sourceaddr.s_addr = htonl(source);
         mreq_source.imr_interface.s_addr = htonl(interf);
         opt = (join) ? IP_ADD_SOURCE_MEMBERSHIP : IP_DROP_SOURCE_MEMBERSHIP;
         optval = (void*)&mreq_source;
         optlen = sizeof(mreq_source);
+#endif
     }
 
     n = setsockopt(fdval(env,fdo), IPPROTO_IP, opt, optval, optlen);
@@ -440,6 +536,10 @@
 Java_sun_nio_ch_Net_blockOrUnblock4(JNIEnv *env, jobject this, jboolean block, jobject fdo,
                                     jint group, jint interf, jint source)
 {
+#ifdef MACOSX
+    /* no IPv4 exclude-mode filtering for now */
+    return IOS_UNAVAILABLE;
+#else
     struct my_ip_mreq_source mreq_source;
     int n;
     int opt = (block) ? IP_BLOCK_SOURCE : IP_UNBLOCK_SOURCE;
@@ -456,6 +556,7 @@
         handleSocketError(env, errno);
     }
     return 0;
+#endif
 }
 
 JNIEXPORT jint JNICALL
@@ -475,8 +576,8 @@
         optval = (void*)&mreq6;
         optlen = sizeof(mreq6);
     } else {
-#ifdef __linux__
-        /* Include-mode filtering broken on Linux at least to 2.6.24 */
+#if defined (__linux__) || defined(MACOSX)
+        /* Include-mode filtering broken on Mac OS & Linux at least to 2.6.24 */
         return IOS_UNAVAILABLE;
 #else
         initGroupSourceReq(env, group, index, source, &req);
@@ -504,6 +605,10 @@
                                     jbyteArray group, jint index, jbyteArray source)
 {
 #ifdef AF_INET6
+  #ifdef MACOSX
+    /* no IPv6 exclude-mode filtering for now */
+    return IOS_UNAVAILABLE;
+  #else
     struct my_group_source_req req;
     int n;
     int opt = (block) ? MCAST_BLOCK_SOURCE : MCAST_UNBLOCK_SOURCE;
@@ -518,6 +623,7 @@
         handleSocketError(env, errno);
     }
     return 0;
+  #endif
 #else
     JNU_ThrowInternalError(env, "Should not get here");
     return IOS_THROWN;
@@ -528,7 +634,7 @@
 Java_sun_nio_ch_Net_setInterface4(JNIEnv* env, jobject this, jobject fdo, jint interf)
 {
     struct in_addr in;
-    int arglen = sizeof(struct in_addr);
+    socklen_t arglen = sizeof(struct in_addr);
     int n;
 
     in.s_addr = htonl(interf);
@@ -559,7 +665,7 @@
 Java_sun_nio_ch_Net_setInterface6(JNIEnv* env, jobject this, jobject fdo, jint index)
 {
     int value = (jint)index;
-    int arglen = sizeof(value);
+    socklen_t arglen = sizeof(value);
     int n;
 
     n = setsockopt(fdval(env, fdo), IPPROTO_IPV6, IPV6_MULTICAST_IF,
@@ -602,9 +708,11 @@
     switch (errorValue) {
         case EINPROGRESS:       /* Non-blocking connect */
             return 0;
+#ifdef EPROTO
         case EPROTO:
             xn = JNU_JAVANETPKG "ProtocolException";
             break;
+#endif
         case ECONNREFUSED:
             xn = JNU_JAVANETPKG "ConnectException";
             break;