Minor updates to spec, and fix test issues unixdomainchannels
authormichaelm
Fri, 08 Nov 2019 09:46:55 +0000
branchunixdomainchannels
changeset 58981 5c79956cc7d7
parent 58939 aca099f4b3ec
child 58988 b88e23c84b23
Minor updates to spec, and fix test issues
src/java.base/share/classes/java/nio/channels/ServerSocketChannel.java
src/java.base/share/classes/java/nio/channels/SocketChannel.java
src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java
src/java.base/windows/native/libnio/ch/Net.c
test/jdk/jdk/nio/Basic.java
--- a/src/java.base/share/classes/java/nio/channels/ServerSocketChannel.java	Tue Nov 05 18:34:02 2019 +0000
+++ b/src/java.base/share/classes/java/nio/channels/ServerSocketChannel.java	Fri Nov 08 09:46:55 2019 +0000
@@ -37,7 +37,7 @@
 /**
  * A selectable channel for stream-oriented listening sockets.
  *
- * <p> A server-socket channel is created by invoking the open methods of this class.
+ * <p> A server-socket channel is created by invoking one of the open methods of this class.
  * It is not possible to create a channel for an arbitrary,
  * pre-existing {@link ServerSocket}. A newly-created server-socket channel is
  * open but not yet bound.  An attempt to invoke the {@link #accept() accept}
@@ -46,11 +46,11 @@
  * {@link #bind(java.net.SocketAddress,int) bind} methods defined by this class.
  *
  * <p>Two kinds of server-socket channel are supported: <i>IP</i> (Internet Protocol)
- * and <i>unix domain</i> depending on which open method is used to create them and which subtype of
+ * and <i>Unix Domain</i> depending on which open method is used to create them and which subtype of
  * {@link SocketAddress} that they support for local and remote addresses.
  * <i>IP</i> channels are created using {@link #open()}. They use {@link
  * InetSocketAddress} addresses and support both IPv4 and IPv6 TCP/IP.
- * <i>unix domain</i> channels are created using {@link #open(ProtocolFamily)}
+ * <i>Unix Domain</i> channels are created using {@link #open(ProtocolFamily)}
  * with the family parameter set to {@link StandardProtocolFamily#UNIX}.
  * They use {@link UnixDomainSocketAddress}es and also
  * do not support the {@link #socket()} method.
@@ -84,7 +84,7 @@
  * <p> Server-socket channels are safe for use by multiple concurrent threads.
  * </p>
  *
- * <p><i>Unix domain</i> server-socket channels support a subset of the options listed above.
+ * <p><i>Unix Domain</i> server-socket channels support a subset of the options listed above.
  *
  * @author Mark Reinhold
  * @author JSR-51 Expert Group
@@ -186,7 +186,7 @@
      * @throws  SecurityException
      *          If a security manager has been installed and its
      *          {@link SecurityManager#checkListen checkListen} method denies
-     *          the operation for <i>IP</i> channels. Or with <i>unix domain</i>
+     *          the operation for <i>IP</i> channels. Or with <i>Unix Domain</i>
      *          channels, if the security manager denies "read" or "write"
      *          {@link java.io.FilePermission} for the local path.
      *
@@ -213,7 +213,7 @@
      * the value {@code 0}, or a negative value, then an implementation specific
      * default is used.
      *
-     * <p> Note, for <i>Unix domain</i> channels, a file is created in the file-system
+     * <p> Note, for <i>Unix Domain</i> channels, a file is created in the file-system
      * with the same path name as this channel's bound {@link UnixDomainSocketAddress}.
      * This file persists after the channel is closed, and must be removed before
      * another channel can bind to the same name.
@@ -237,7 +237,7 @@
      * @throws  SecurityException
      *          If a security manager has been installed and its
      *          {@link SecurityManager#checkListen checkListen} method denies
-     *          the operation for <i>IP</i> channels. Or with <i>unix domain</i>
+     *          the operation for <i>IP</i> channels; or in the case of <i>Unix Domain</i>
      *          channels, if the security manager denies "read" or "write"
      *          {@link java.io.FilePermission} for the local path.
      *
@@ -259,13 +259,14 @@
 
     /**
      * Retrieves a server socket associated with this channel if it is an <i>IP</i>
-     * channel. The operation is not supported for <i>unix domain</i> channels.
+     * channel. The operation is not supported for <i>Unix Domain</i> channels.
      *
      * <p> The returned object will not declare any public methods that are not
      * declared in the {@link java.net.ServerSocket} class.  </p>
      *
      * @return  A server socket associated with this channel
-     * @throws UnsupportedOperationException if this is a Unix domain channel
+     *
+     * @throws UnsupportedOperationException if this is a Unix Domain channel
      */
     public abstract ServerSocket socket();
 
@@ -288,7 +289,7 @@
      * permitted by the security manager's {@link
      * java.lang.SecurityManager#checkAccept checkAccept} method.  </p>
      *
-     * <p> For <i>unix domain</i> channels, this method performs a security
+     * <p> For <i>Unix Domain</i> channels, this method performs a security
      * manager {@link SecurityManager#checkPermission(Permission)} using
      * a {@link java.io.FilePermission} constructed with the path from the
      * remote address and "read,write" as the actions.
@@ -325,8 +326,8 @@
 
     /**
      * {@inheritDoc}
-     * Where the channel is bound to a <i>Unix domain</i> address, the return
-     * value from this this method is of type  {@link UnixDomainSocketAddress}.
+     * Where the channel is bound to a <i>Unix Domain</i> address, the return
+     * value from this method is of type  {@link UnixDomainSocketAddress}.
      * <p>
      * If there is a security manager set and this is an <i>IP</i> channel,
      * {@code checkConnect} method is
@@ -336,7 +337,7 @@
      * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
      * local port of the channel's socket is returned.
      * <p>
-     * If there is a security manager set and this is a <i>unix domain</i> channel,
+     * If there is a security manager set and this is a <i>Unix Domain</i> channel,
      * then {@link SecurityManager#checkPermission(Permission)} is called using
      * a {@link java.io.FilePermission} constructed with the path from the
      * local address and "read" as the action. If this check fails
@@ -344,8 +345,8 @@
      * is returned.
      *
      * @return  The {@code SocketAddress} that the socket is bound to, or the
-     *          {@code SocketAddress} representing the loopback address if
-     *          denied by the security manager, or {@code null} if the
+     *          {@code SocketAddress} representing the loopback address or empty
+     *          pathname if denied by the security manager, or {@code null} if the
      *          channel's socket is not bound
      *
      * @throws  ClosedChannelException     {@inheritDoc}
--- a/src/java.base/share/classes/java/nio/channels/SocketChannel.java	Tue Nov 05 18:34:02 2019 +0000
+++ b/src/java.base/share/classes/java/nio/channels/SocketChannel.java	Fri Nov 08 09:46:55 2019 +0000
@@ -67,14 +67,16 @@
  * AsynchronousCloseException}.
  *
  * <p>Two kinds of socket channel are supported: <i>IP</i> (Internet Protocol) and
- * <i>unix domain</i> depending on which open method is used to create them and which
+ * <i>Unix Domain</i> depending on which open method is used to create them and which
  * subtype of {@link SocketAddress} that they support for local and remote addresses.
  * <i>IP</i> channels are created using {@link #open()}. They use {@link
  * InetSocketAddress} addresses and support both IPv4 and IPv6 TCP/IP.
- * <i>unix domain</i> channels are created using {@link #open(ProtocolFamily)}
+ * <i>Unix Domain</i> channels are created using {@link #open(ProtocolFamily)}
  * with the family parameter set to {@link StandardProtocolFamily#UNIX}.
  * They use {@link UnixDomainSocketAddress}es and also
- * do not support the {@link #socket()} method.
+ * do not support the {@link #socket()} method. Note, it is also possible to
+ * create channels that support either IPv4 or IPv6 only through the
+ * {@link #open(ProtocolFamily)} method.
  *
  * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
  * setOption} method. <i>IP</i> socket channels support the following options:
@@ -126,7 +128,7 @@
  * or write operation while an invocation of one of these methods is in
  * progress will block until that invocation is complete.  </p>
  *
- * <p><i>Unix domain</i> channels support a subset of the options listed above.
+ * <p><i>Unix Domain</i> channels support a subset of the options listed above.
  *
  * @author Mark Reinhold
  * @author JSR-51 Expert Group
@@ -183,18 +185,18 @@
     /**
      * Opens a socket channel and connects it to a remote address.
      * Depending on the type of {@link SocketAddress} supplied, the returned object
-     * is an <i>IP</i> or <i>unix domain</i> channel.
+     * is an <i>IP</i> or <i>Unix Domain</i> channel.
      *
      * <p> For {@link InetSocketAddress}es this convenience method works as if by invoking the {@link #open()}
      * method, invoking the {@link #connect(SocketAddress) connect} method upon
-     * the resulting socket channel, passing it {@code remote}, and then
-     * returning that channel.  </p>
+     * the resulting socket channel, passing it {@code remote}, which must be an
+     * {@link InetSocketAddress} and then returning that channel.  </p>
      *
      * <p> For {@link UnixDomainSocketAddress}es it works as if by invoking the {@link
      * #open(ProtocolFamily)} method with {@link StandardProtocolFamily#UNIX} as parameter,
      * invoking the {@link #connect(SocketAddress) connect} method upon
-     * the resulting socket channel, passing it {@code remote}, and then
-     * returning that channel.  </p>
+     * the resulting socket channel, passing it {@code remote}, which must be a
+     * {@link UnixDomainSocketAddress} and then returning that channel.  </p>
      *
      * @param  remote
      *         The remote address to which the new channel is to be connected
@@ -272,7 +274,7 @@
     /**
      * {@inheritDoc}
      *
-     * <p> Note, for <i>Unix domain</i> channels, a file is created in the file-system
+     * <p> Note, for <i>Unix Domain</i> channels, a file is created in the file-system
      * with the same name as this channel's bound address. This file persists after
      * the channel is closed, and must be removed before another channel can bind
      * to the same name.
@@ -287,7 +289,7 @@
      * @throws  SecurityException
      *          If a security manager has been installed and its
      *          {@link SecurityManager#checkListen checkListen} method denies
-     *          the operation for <i>IP</i> channels or for <i>unix domain</i>
+     *          the operation for <i>IP</i> channels; or for <i>Unix Domain</i>
      *          channels, if the security manager denies "read" or "write"
      *          {@link java.io.FilePermission} for the local path.
      *
@@ -352,13 +354,14 @@
 
     /**
      * Retrieves a socket associated with this channel if it is an <i>IP</i>
-     * channel. The operation is not supported for <i>unix domain</i> channels.
+     * channel. The operation is not supported for <i>Unix Domain</i> channels.
      *
      * <p> The returned object will not declare any public methods that are not
      * declared in the {@link java.net.Socket} class.  </p>
      *
      * @return  A socket associated with this channel
-     * @throws UnsupportedOperationException is this is a Unix domain channel
+     *
+     * @throws UnsupportedOperationException is this is a <i>Unix Domain</i> channel
      */
     public abstract Socket socket();
 
@@ -400,7 +403,7 @@
      * java.lang.SecurityManager#checkConnect checkConnect} method permits
      * connecting to the address and port number of the given remote endpoint.
      *
-     * <p> For <i>unix domain</i> channels, this method performs a security
+     * <p> For <i>Unix Domain</i> channels, this method performs a security
      * manager {@link SecurityManager#checkPermission(Permission)} using
      * a {@link java.io.FilePermission} constructed with the path from the
      * destination address and "read,write" as the actions.
@@ -512,7 +515,7 @@
      * socket address then the return value from this method is of type {@link
      * java.net.InetSocketAddress}.
      *
-     * <p> Where the channel is bound and connected to a <i>Unix domain</i>
+     * <p> Where the channel is bound and connected to a <i>Unix Domain</i>
      * address, the returned address is a {@link UnixDomainSocketAddress}
      *
      * @return  The remote address; {@code null} if the channel's socket is not
@@ -582,13 +585,16 @@
      * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
      * local port of the channel's socket is returned.
      * <p>
-     * If there is a security manager set and this is an <i>unix domain</i> channel,
-     * then this returns a {@link UnixDomainSocketAddress} corresponding to the
-     * bound address.
+     * If there is a security manager set and this is a <i>Unix Domain</i> channel,
+     * {@code checkPermission} is called with a {@link FilePermission} whose {@code
+     * path} is the path of the bound address and actions is {@code "read"}
+     * and if the operation is allowed a {@link UnixDomainSocketAddress} 
+     * corresponding to the bound address is returned. If not, then an address with
+     * an empty path is returned.
      *
      * @return  The {@code SocketAddress} that the socket is bound to, or the
-     *          {@code SocketAddress} representing the loopback address if
-     *          denied by the security manager, or {@code null} if the
+     *          {@code SocketAddress} representing the loopback address or an
+     *          empty pathname, if denied by the security manager, or {@code null} if the
      *          channel's socket is not bound
      *
      * @throws  ClosedChannelException     {@inheritDoc}
--- a/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java	Tue Nov 05 18:34:02 2019 +0000
+++ b/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java	Fri Nov 08 09:46:55 2019 +0000
@@ -115,6 +115,21 @@
         }
     }
 
+    public static class InheritedUnixServerSocketChannelImpl extends UnixDomainServerSocketChannelImpl {
+
+        InheritedUnixServerSocketChannelImpl(SelectorProvider sp, FileDescriptor fd)
+            throws IOException
+        {
+            super(sp, fd, true);
+        }
+
+        @Override
+        protected void implCloseSelectableChannel() throws IOException {
+            super.implCloseSelectableChannel();
+            detachIOStreams();
+        }
+    }
+
     public static class InheritedInetServerSocketChannelImpl extends
         InetServerSocketChannelImpl {
 
@@ -214,8 +229,7 @@
                 if (isConnected(fdVal)) {
                     return new InheritedUnixSocketChannelImpl(provider, fd);
                 } else {
-                    // listener. unsupported.
-                    return null;
+                    return new InheritedUnixServerSocketChannelImpl(provider, fd);
                 }
             }
             InetAddress ia = peerAddress0(fdVal);
--- a/src/java.base/windows/native/libnio/ch/Net.c	Tue Nov 05 18:34:02 2019 +0000
+++ b/src/java.base/windows/native/libnio/ch/Net.c	Fri Nov 08 09:46:55 2019 +0000
@@ -141,7 +141,7 @@
 Java_sun_nio_ch_Net_unixDomainSocket0(JNIEnv *env, jclass cl)
 {
     SOCKET fd = socket(PF_UNIX, SOCK_STREAM, 0);
-    if (fd < 0) {
+    if (fd == INVALID_SOCKET) {
         return handleSocketError(env, errno);
     }
     return (int)fd;
--- a/test/jdk/jdk/nio/Basic.java	Tue Nov 05 18:34:02 2019 +0000
+++ b/test/jdk/jdk/nio/Basic.java	Fri Nov 08 09:46:55 2019 +0000
@@ -265,11 +265,20 @@
     }
 
     private static FileDescriptor getFD(SocketChannel sc) {
+	return getFD1(sc, sc.getClass());
+    }
+
+    private static FileDescriptor getFD1(SocketChannel sc, Class<?> clazz) {
         try {
-            Class<?> clazz = sc.getClass();
             Field f = clazz.getDeclaredField("fd");
             f.setAccessible(true);
             return (FileDescriptor) f.get(sc);
+        } catch (NoSuchFieldException e1) {
+	    Class<?> superclass = clazz.getSuperclass();
+	    if (superclass == null)
+		throw new Error(e1);
+	    else
+		return getFD1(sc, superclass);
         } catch (Exception e) {
             throw new Error(e);
         }