test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/libInheritedChannel.c
changeset 58295 7973073dd048
parent 52778 dbbf46b13d52
--- a/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/libInheritedChannel.c	Tue Sep 24 17:08:19 2019 +0200
+++ b/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/libInheritedChannel.c	Tue Sep 24 16:19:11 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,10 @@
  */
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/un.h>
 #include <unistd.h>
 #include <dirent.h>
 #include <sys/stat.h>
@@ -147,19 +149,18 @@
 
     /*
      * We need to close all file descriptors except for serviceFd. To
-     * get the list of open file descriptos we read through /proc/self/fd
+     * get the list of open file descriptos we read through /proc/self/fd (/dev/fd)
      * but to open this requires a file descriptor. We could use a specific
      * file descriptor and fdopendir but Linux doesn't seem to support
      * fdopendir. Instead we use opendir and make an assumption on the
      * file descriptor that is used (by opening & closing a file).
      */
-    thisFd = open("/dev/null", O_RDONLY);
+    thisFd = open("/dev/fd", O_RDONLY);
     if (thisFd < 0) {
         _exit(-1);
     }
-    close(thisFd);
 
-    if ((dp = opendir("/proc/self/fd")) == NULL) {
+    if ((dp = fdopendir(thisFd)) == NULL) {
         _exit(-1);
     }
 
@@ -216,6 +217,65 @@
     return result;
 }
 
+JNIEXPORT jint JNICALL Java_UnixDomainSocket_create
+  (JNIEnv *env, jclass cls)
+{
+    int sock = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (sock == -1) {
+        ThrowException(env, "java/io/IOException", "socket create error");
+    }
+    return sock;
+}
+
+JNIEXPORT void JNICALL Java_UnixDomainSocket_bind0
+  (JNIEnv *env, jclass cls, jint sock, jstring name)
+{
+    struct sockaddr_un addr;
+    const char *nameUtf = (*env)->GetStringUTFChars(env, name, NULL);
+    int ret = -1;
+    unlink(nameUtf);
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    strncpy(addr.sun_path, nameUtf, strlen(nameUtf));
+    ret = bind(sock, (const struct sockaddr*)&addr, sizeof(addr));
+    if (ret == -1) {
+        ThrowException(env, "java/io/IOException", "socket bind error");
+    }
+    ret = listen(sock, 5);
+    if (ret == -1) {
+        ThrowException(env, "java/io/IOException", "socket bind error");
+    }
+    (*env)->ReleaseStringUTFChars(env, name, nameUtf);
+}
+
+JNIEXPORT jint JNICALL Java_UnixDomainSocket_accept0
+  (JNIEnv *env, jclass cls, jint sock)
+{
+    struct sockaddr_storage addr;
+    socklen_t len = sizeof(addr);
+    int ret = accept(sock, (struct sockaddr *)&addr, &len);
+    if (ret == -1)
+        ThrowException(env, "java/io/IOException", "socket accept error");
+    return ret;
+}
+
+JNIEXPORT void JNICALL Java_UnixDomainSocket_connect0
+  (JNIEnv *env, jclass cls, jint fd, jstring name)
+{
+    struct sockaddr_un addr;
+    const char *nameUtf = (*env)->GetStringUTFChars(env, name, NULL);
+    int ret = -1;
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    strncpy(addr.sun_path, nameUtf, strlen(nameUtf));
+    ret = connect(fd, (const struct sockaddr*)&addr, sizeof(addr));
+    if (ret == -1) {
+        ThrowException(env, "java/io/IOException", "socket connect error");
+    }
+    (*env)->ReleaseStringUTFChars(env, name, nameUtf);
+}
+
+
 JNIEXPORT jint JNICALL Java_UnixDomainSocket_read0
   (JNIEnv *env, jclass cls, jint fd)
 {
@@ -243,7 +303,12 @@
 }
 
 JNIEXPORT void JNICALL Java_UnixDomainSocket_close0
-  (JNIEnv *env, jclass cls, jint fd)
+  (JNIEnv *env, jclass cls, jint fd, jstring name)
 {
     close(fd);
+    if (name != NULL) {
+        const char *nameUtf = (*env)->GetStringUTFChars(env, name, NULL);
+        unlink(nameUtf);
+        (*env)->ReleaseStringUTFChars(env, name, nameUtf);
+    }
 }