1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.net; 27 28 import java.io.ObjectStreamException; 29 import java.io.Serializable; 30 import java.net.SocketAddress; 31 import java.nio.channels.SocketChannel; 32 import java.nio.file.FileSystem; 33 import java.nio.file.FileSystems; 34 import java.nio.file.InvalidPathException; 35 import java.nio.file.Path; 36 37 /** 38 * A <a href="package-summary.html#unixdomain">Unix domain</a> socket address. 39 * A Unix domain socket address encapsulates a file-system path that Unix domain sockets 40 * bind or connect to. 41 * 42 * <p> An <a id="unnamed"></a><i>unnamed</i> {@code UnixDomainSocketAddress} has 43 * an empty path. The local address of a {@link SocketChannel} to a Unix domain socket 44 * that is <i>automatically</i> or <i>implicitly</i> bound will be unnamed. 45 * 46 * <p> {@link Path} objects used to create instances of this class must be obtained 47 * from the {@linkplain FileSystems#getDefault system-default} file system. 48 * 49 * @see java.nio.channels.SocketChannel 50 * @see java.nio.channels.ServerSocketChannel 51 * @since 16 52 */ 53 public final class UnixDomainSocketAddress extends SocketAddress { 54 @java.io.Serial 55 static final long serialVersionUID = 92902496589351288L; 56 57 private final transient Path path; 58 59 /** 60 * A serial proxy for all {@link UnixDomainSocketAddress} instances. 61 * It captures the file path name and reconstructs using the public static 62 * {@link #of(String) factory}. 63 * 64 * @serial include 65 */ 66 private static final class Ser implements Serializable { 67 @java.io.Serial 68 static final long serialVersionUID = -7955684448513979814L; 69 70 /** 71 * The path name. 72 * @serial 73 */ 74 private final String pathname; 75 76 Ser(String pathname) { 77 this.pathname = pathname; 78 } 79 80 /** 81 * Creates a {@link UnixDomainSocketAddress} instance, by an invocation 82 * of the {@link #of(String) factory} method passing the path name. 83 * @return a UnixDomainSocketAddress 84 */ 85 @java.io.Serial 86 private Object readResolve() { 87 return UnixDomainSocketAddress.of(pathname); 88 } 89 } 90 91 /** 92 * Returns a 93 * <a href="{@docRoot}/serialized-form.html#java.net.UnixDomainSocketAddress.Ser"> 94 * Ser</a> containing the path name of this instance. 95 * 96 * @return a {@link Ser} 97 * representing the path name of this instance 98 */ 99 @java.io.Serial 100 private Object writeReplace() throws ObjectStreamException { 101 return new Ser(path.toString()); 102 } 103 104 /** 105 * Throws InvalidObjectException, always. 106 * @param s the stream 107 * @throws java.io.InvalidObjectException always 108 */ 109 @java.io.Serial 110 private void readObject(java.io.ObjectInputStream s) 111 throws java.io.InvalidObjectException 112 { 113 throw new java.io.InvalidObjectException("Proxy required"); 114 } 115 116 /** 117 * Throws InvalidObjectException, always. 118 * @throws java.io.InvalidObjectException always 119 */ 120 @java.io.Serial 121 private void readObjectNoData() 122 throws java.io.InvalidObjectException 123 { 124 throw new java.io.InvalidObjectException("Proxy required"); 125 } 126 127 private UnixDomainSocketAddress(Path path) { 128 FileSystem fs = path.getFileSystem(); 129 if (fs != FileSystems.getDefault()) { 130 throw new IllegalArgumentException(); 131 } 132 if (fs.getClass().getModule() != Object.class.getModule()) { 133 throw new IllegalArgumentException(); 134 } 135 this.path = path; 136 } 137 138 /** 139 * Create a UnixDomainSocketAddress from the given path string. 140 * 141 * @param pathname 142 * The path string, which can be empty 143 * 144 * @return A UnixDomainSocketAddress 145 * 146 * @throws InvalidPathException 147 * If the path cannot be converted to a Path 148 * 149 * @throws NullPointerException if pathname is {@code null} 150 */ 151 public static UnixDomainSocketAddress of(String pathname) { 152 return of(Path.of(pathname)); 153 } 154 155 /** 156 * Create a UnixDomainSocketAddress for the given path. 157 * 158 * @param path 159 * The path to the socket, which can be empty 160 * 161 * @return A UnixDomainSocketAddress 162 * 163 * @throws IllegalArgumentException 164 * If the path is not associated with the default file system 165 * 166 * @throws NullPointerException if path is {@code null} 167 */ 168 public static UnixDomainSocketAddress of(Path path) { 169 return new UnixDomainSocketAddress(path); 170 } 171 172 /** 173 * Return this address's path. 174 * 175 * @return this address's path 176 */ 177 public Path getPath() { 178 return path; 179 } 180 181 /** 182 * Returns the hash code of this {@code UnixDomainSocketAddress} 183 */ 184 @Override 185 public int hashCode() { 186 return path.hashCode(); 187 } 188 189 /** 190 * Compares this address with another object. 191 * 192 * @return true if the path fields are equal 193 */ 194 @Override 195 public boolean equals(Object o) { 196 if (!(o instanceof UnixDomainSocketAddress)) 197 return false; 198 UnixDomainSocketAddress that = (UnixDomainSocketAddress)o; 199 return this.path.equals(that.path); 200 } 201 202 /** 203 * Returns a string representation of this {@code UnixDomainSocketAddress}. 204 * 205 * @return this address's path which may be empty for an unnamed address 206 */ 207 @Override 208 public String toString() { 209 return path.toString(); 210 } 211 }