< prev index next >

src/java.base/unix/native/libnio/ch/Net.c

Print this page
rev 55750 : UDS support, temporary commit

@@ -146,10 +146,13 @@
 
 #endif  /* _AIX */
 
 static jclass isa_class;        /* java.net.InetSocketAddress */
 static jmethodID isa_ctorID;    /* InetSocketAddress(InetAddress, int) */
+static jclass usa_class;        /* java.net.UnixSocketAddress */
+static jmethodID usa_ctor;      /* UnixSocketAddress() */
+static jmethodID usa_ctorBytes; /* UnixSocketAddress(byte[]) */
 
 JNIEXPORT void JNICALL
 Java_sun_nio_ch_Net_initIDs(JNIEnv *env, jclass clazz)
 {
      jclass cls = (*env)->FindClass(env, "java/net/InetSocketAddress");

@@ -160,10 +163,22 @@
          return;
      }
      isa_ctorID = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/net/InetAddress;I)V");
      CHECK_NULL(isa_ctorID);
 
+     cls = (*env)->FindClass(env, "java/net/UnixSocketAddress");
+     CHECK_NULL(cls);
+     usa_class = (*env)->NewGlobalRef(env, cls);
+     if (usa_class == NULL) {
+         JNU_ThrowOutOfMemoryError(env, NULL);
+         return;
+     }
+     usa_ctor = (*env)->GetMethodID(env, cls, "<init>", "()V");
+     CHECK_NULL(usa_ctor);
+     usa_ctorBytes = (*env)->GetMethodID(env, cls, "<init>", "([B)V");
+     CHECK_NULL(usa_ctorBytes);
+
      initInetAddressIDs(env);
 }
 
 JNIEXPORT jboolean JNICALL
 Java_sun_nio_ch_Net_isIPv6Available0(JNIEnv* env, jclass cl)

@@ -271,10 +286,21 @@
     }
 #endif
     return fd;
 }
 
+JNIEXPORT jint JNICALL 
+Java_sun_nio_ch_Net_socket1 (JNIEnv *env, jclass clazz, jboolean stream) 
+{
+    int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
+    int fd = socket(AF_UNIX, type, 0);
+    if (fd < 0) {
+        return handleSocketError(env, errno);
+    }
+    return fd;
+}
+
 JNIEXPORT void JNICALL
 Java_sun_nio_ch_Net_bind0(JNIEnv *env, jclass clazz, jobject fdo, jboolean preferIPv6,
                           jboolean useExclBind, jobject iao, int port)
 {
     SOCKETADDRESS sa;

@@ -291,10 +317,29 @@
         handleSocketError(env, errno);
     }
 }
 
 JNIEXPORT void JNICALL
+Java_sun_nio_ch_Net_bind1(JNIEnv *env, jclass clazz, jobject fdo, jbyteArray uao)
+{
+    SOCKETADDRESS sa;
+    memset(&sa, 0x00, sizeof (sa));
+    sa.sau.sun_family = AF_UNIX;
+    size_t uao_len = (* env) -> GetArrayLength(env, uao);
+    size_t sa_len = sizeof (sa.sau.sun_path);
+    if (uao_len > sa_len) {
+        // TODO: throw propper exception
+        return;
+    }
+    (* env) -> GetByteArrayRegion(env, uao, 0, uao_len, (jbyte *) sa.sau.sun_path);
+    int rv = bind(fdval(env, fdo), &sa.sa, sa_len);
+    if (rv != 0) {
+        handleSocketError(env, errno);
+    }
+}
+
+JNIEXPORT void JNICALL
 Java_sun_nio_ch_Net_listen(JNIEnv *env, jclass cl, jobject fdo, jint backlog)
 {
     if (listen(fdval(env, fdo), backlog) < 0)
         handleSocketError(env, errno);
 }

@@ -322,10 +367,37 @@
     }
     return 1;
 }
 
 JNIEXPORT jint JNICALL
+Java_sun_nio_ch_Net_connect1(JNIEnv *env, jclass clazz, jobject fdo, jbyteArray uao)
+{
+    SOCKETADDRESS sa;
+    memset(&sa, 0x00, sizeof (sa));
+    sa.sau.sun_family = AF_UNIX;
+    size_t uao_len = (* env) -> GetArrayLength(env, uao);
+    size_t sa_len = sizeof (sa.sau.sun_path);
+    if (uao_len > sa_len) {
+        // TODO: throw propper exception
+        return IOS_UNAVAILABLE;
+    }
+    (* env) -> GetByteArrayRegion(env, uao, 0, uao_len, (jbyte *) sa.sau.sun_path);
+    
+    // TODO: refactoring, common method
+    int rv = connect(fdval(env, fdo), &sa.sa, sa_len);
+    if (rv != 0) {
+        if (errno == EINPROGRESS) {
+            return IOS_UNAVAILABLE;
+        } else if (errno == EINTR) {
+            return IOS_INTERRUPTED;
+        }
+        return handleSocketError(env, errno);
+    }
+    return 1;
+}
+
+JNIEXPORT jint JNICALL
 Java_sun_nio_ch_Net_accept(JNIEnv *env, jclass clazz, jobject fdo, jobject newfdo,
                            jobjectArray isaa)
 {
     jint fd = fdval(env, fdo);
     jint newfd;

@@ -356,18 +428,27 @@
         return IOS_THROWN;
     }
 
     setfdval(env, newfdo, newfd);
 
+    if (sa.sa.sa_family == AF_INET || sa.sa.sa_family == AF_INET6) {
     remote_ia = NET_SockaddrToInetAddress(env, &sa, (int *)&remote_port);
     CHECK_NULL_RETURN(remote_ia, IOS_THROWN);
 
     isa = (*env)->NewObject(env, isa_class, isa_ctorID, remote_ia, remote_port);
     CHECK_NULL_RETURN(isa, IOS_THROWN);
     (*env)->SetObjectArrayElement(env, isaa, 0, isa);
 
     return 1;
+    } else if (sa.sa.sa_family == AF_UNIX) {
+        isa = (*env)->NewObject(env, usa_class, usa_ctor);
+        CHECK_NULL_RETURN(isa, IOS_THROWN);
+        (*env)->SetObjectArrayElement(env, isaa, 0, isa);
+        return 1;
+    } else {
+        return -6; // UNSUPPORTED_CASE
+    }
 }
 
 JNIEXPORT jint JNICALL
 Java_sun_nio_ch_Net_localPort(JNIEnv *env, jclass clazz, jobject fdo)
 {

@@ -431,10 +512,33 @@
 #endif /* _ALLBSD_SOURCE */
     }
     return NET_SockaddrToInetAddress(env, &sa, &port);
 }
 
+JNIEXPORT jobject JNICALL
+Java_sun_nio_ch_Net_localSocketAddress(JNIEnv *env, jclass clazz, jobject fdo) 
+{
+    SOCKETADDRESS sa;
+    socklen_t sa_len = sizeof (SOCKETADDRESS);
+    memset(&sa, 0x00, sa_len);
+    if (getsockname(fdval(env, fdo), &sa.sa, &sa_len) != 0) {
+        return NULL; // TODO: exception?
+    }
+
+    if (sa.sa.sa_family == AF_UNIX) {
+        jbyteArray addr = (*env)->NewByteArray(env, sizeof(sa.sau.sun_path));
+        (*env)->SetByteArrayRegion(env, addr, 0, sizeof(sa.sau.sun_path), (jbyte *) sa.sau.sun_path);
+        return (*env)->NewObject(env, usa_class, usa_ctorBytes, addr);
+    } else if (sa.sa.sa_family == AF_INET || sa.sa.sa_family == AF_INET6) {
+        jobject address = Java_sun_nio_ch_Net_localInetAddress(env, clazz, fdo);
+        jint port = Java_sun_nio_ch_Net_localPort(env, clazz, fdo);
+        return (*env)->NewObject(env, isa_class, isa_ctorID, address, port);
+    } else {
+        return NULL; // TODO: exception?
+    }
+}
+
 JNIEXPORT jint JNICALL
 Java_sun_nio_ch_Net_remotePort(JNIEnv *env, jclass clazz, jobject fdo)
 {
     SOCKETADDRESS sa;
     socklen_t sa_len = sizeof(sa);
< prev index next >