inherited channels fix unixdomainchannels
authormichaelm
Fri, 08 Nov 2019 16:22:21 +0000
branchunixdomainchannels
changeset 58988 b88e23c84b23
parent 58981 5c79956cc7d7
child 59003 aaba7cc40951
inherited channels fix
src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java
src/java.base/unix/native/libnio/ch/InheritedChannel.c
test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/InheritedChannelTest.java
test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/UnixDomainChannelTest.java
--- a/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java	Fri Nov 08 09:46:55 2019 +0000
+++ b/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java	Fri Nov 08 16:22:21 2019 +0000
@@ -39,6 +39,7 @@
 import java.nio.channels.SocketChannel;
 import java.nio.channels.ServerSocketChannel;
 import java.nio.channels.DatagramChannel;
+import java.nio.channels.UnixDomainSocketAddress;
 import java.nio.channels.spi.SelectorProvider;
 
 class InheritedChannel {
@@ -102,10 +103,12 @@
 
     public static class InheritedUnixSocketChannelImpl extends UnixDomainSocketChannelImpl {
 
-        InheritedUnixSocketChannelImpl(SelectorProvider sp, FileDescriptor fd)
+        InheritedUnixSocketChannelImpl(SelectorProvider sp, 
+				FileDescriptor fd,
+				UnixDomainSocketAddress remote )
             throws IOException
         {
-            super(sp, fd, true);
+            super(sp, fd, remote);
         }
 
         @Override
@@ -227,16 +230,18 @@
                 return null;
             if (family == AF_UNIX) {
                 if (isConnected(fdVal)) {
-                    return new InheritedUnixSocketChannelImpl(provider, fd);
+	            UnixDomainSocketAddress sa = peerAddressUnix(fdVal);
+                    return new InheritedUnixSocketChannelImpl(provider, fd, sa);
                 } else {
                     return new InheritedUnixServerSocketChannelImpl(provider, fd);
                 }
             }
-            InetAddress ia = peerAddress0(fdVal);
+            InetAddress ia = peerAddressInet(fdVal);
             if (ia == null) {
                c = new InheritedInetServerSocketChannelImpl(provider, fd);
             } else {
                int port = peerPort0(fdVal);
+
                assert port > 0;
                InetSocketAddress isa = new InetSocketAddress(ia, port);
                c = new InheritedInetSocketChannelImpl(provider, fd, isa);
@@ -283,7 +288,8 @@
     private static native void close0(int fd) throws IOException;
     private static native int soType0(int fd);
     private static native int addressFamily(int fd);
-    private static native InetAddress peerAddress0(int fd);
+    private static native InetAddress peerAddressInet(int fd);
+    private static native UnixDomainSocketAddress peerAddressUnix(int fd);
     private static native int peerPort0(int fd);
 
     // return true if socket is connected to a peer
--- a/src/java.base/unix/native/libnio/ch/InheritedChannel.c	Fri Nov 08 09:46:55 2019 +0000
+++ b/src/java.base/unix/native/libnio/ch/InheritedChannel.c	Fri Nov 08 16:22:21 2019 +0000
@@ -37,7 +37,7 @@
 
 #include "sun_nio_ch_InheritedChannel.h"
 
-static int matchFamily(SOCKETADDRESS *sa) {
+static int matchFamilyInet(SOCKETADDRESS *sa) {
     return (sa->sa.sa_family == (ipv6_available() ? AF_INET6 : AF_INET));
 }
 
@@ -49,7 +49,7 @@
 }
 
 JNIEXPORT jobject JNICALL
-Java_sun_nio_ch_InheritedChannel_peerAddress0(JNIEnv *env, jclass cla, jint fd)
+Java_sun_nio_ch_InheritedChannel_peerAddressInet(JNIEnv *env, jclass cla, jint fd)
 {
     SOCKETADDRESS sa;
     socklen_t len = sizeof(SOCKETADDRESS);
@@ -57,7 +57,7 @@
     jint remote_port;
 
     if (getpeername(fd, &sa.sa, &len) == 0) {
-        if (matchFamily(&sa)) {
+        if (matchFamilyInet(&sa)) {
             remote_ia = NET_SockaddrToInetAddress(env, &sa, (int *)&remote_port);
         }
     }
@@ -65,6 +65,19 @@
     return remote_ia;
 }
 
+JNIEXPORT jobject JNICALL
+Java_sun_nio_ch_InheritedChannel_peerAddressUnix(JNIEnv *env, jclass cla, jint fd)
+{
+    SOCKETADDRESS sa;
+    socklen_t len = sizeof(SOCKETADDRESS);
+    jobject remote_sa = NULL;
+
+    if (sa.sa.sa_family == AF_UNIX) {
+    	remote_sa = NET_SockaddrToUnixAddress(env, &sa);
+    }
+    return remote_sa;
+}
+
 JNIEXPORT jint JNICALL
 Java_sun_nio_ch_InheritedChannel_peerPort0(JNIEnv *env, jclass cla, jint fd)
 {
@@ -73,9 +86,9 @@
     jint remote_port = -1;
 
     if (getpeername(fd, &sa.sa, &len) == 0) {
-        if (matchFamily(&sa)) {
+        if (matchFamilyInet(&sa)) {
             NET_SockaddrToInetAddress(env, &sa, (int *)&remote_port);
-        }
+	}
     }
 
     return remote_port;
--- a/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/InheritedChannelTest.java	Fri Nov 08 09:46:55 2019 +0000
+++ b/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/InheritedChannelTest.java	Fri Nov 08 16:22:21 2019 +0000
@@ -76,6 +76,7 @@
     public Object[][] testCases() {
         return new Object[][] {
             { "UnixDomainChannelTest", List.of(UnixDomainChannelTest.class.getName())},
+/*
             { "UnixSocketTest", List.of(UnixSocketTest.class.getName())},
             { "StateTest", List.of(StateTest.class.getName()) },
             { "EchoTest",  List.of(EchoTest.class.getName())  },
@@ -97,6 +98,7 @@
                                                            "-Djava.security.policy="
                                                            + POLICY_FAIL)
             }
+*/
         };
     }
 
--- a/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/UnixDomainChannelTest.java	Fri Nov 08 09:46:55 2019 +0000
+++ b/test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/UnixDomainChannelTest.java	Fri Nov 08 16:22:21 2019 +0000
@@ -27,7 +27,7 @@
 import static java.nio.charset.StandardCharsets.ISO_8859_1;
 
 /*
- * Make sure that System.inheritedChannel returns null when given a UNIX domain socket
+ * Make sure that System.inheritedChannel returns the correct type
  */
 
 public class UnixDomainChannelTest {
@@ -45,11 +45,18 @@
                 bc.write(buf);
             } else { // test3
                 // in this case the socket is a listener
-                // we can't write to it. So, use UnixDatagramSocket
-                // to accept a writeable socket
-                UnixDomainSocket listener = new UnixDomainSocket(0); // fd 0
-                UnixDomainSocket sock = listener.accept();
-                sock.write((int)result.charAt(0));
+		if (!(channel instanceof ServerSocketChannel)) {
+                    // we can't write to it. So, use UnixDatagramSocket
+                    // to accept a writeable socket
+                    UnixDomainSocket listener = new UnixDomainSocket(0); // fd 0
+                    UnixDomainSocket sock = listener.accept();
+                    sock.write((int)'X');
+		} else {
+		    ServerSocketChannel server = (ServerSocketChannel)channel;
+		    ByteChannel bc = server.accept();
+                    ByteBuffer buf = ByteBuffer.wrap(result.getBytes(ISO_8859_1));
+                    bc.write(buf);
+		}
             }
         }
     }
@@ -107,7 +114,7 @@
         System.out.println("test3: launching child");
         Launcher.launchWithUnixDomainSocket("UnixDomainChannelTest$Child", listener, "test3");
         sock1.connect("foo.socket");
-        if (sock1.read() != 'N') {
+        if (sock1.read() != 'Y') {
             System.err.println("test3: failed");
             passed = false;
         }