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.file.FileSystem; 32 import java.nio.file.FileSystems; 33 import java.nio.file.InvalidPathException; 34 import java.nio.file.Path; 35 36 /** 37 * A <a href="package-summary.html#unixdomain">Unix domain</a> socket address. 38 * A Unix domain socket address encapsulates a file-system path that Unix domain sockets 39 * bind or connect to. 40 * 41 * <p> An <a id="unnamed"></a><i>unnamed</i> {@code UnixDomainSocketAddress} has 42 * an empty path. The local address of a Unix domain socket that is automatically 43 * bound will be unnamed. 44 * 45 * <p> {@link Path} objects used to create instances of this class must be obtained 46 * from the {@linkplain FileSystems#getDefault system-default} file system. 47 * 48 * @see java.nio.channels.SocketChannel 49 * @see java.nio.channels.ServerSocketChannel 50 * @since 16 51 */ 52 public final class UnixDomainSocketAddress extends SocketAddress { 53 @java.io.Serial 54 static final long serialVersionUID = 92902496589351288L; 55 56 private final transient Path path; 57 58 /** 59 * A serial proxy for all {@link UnixDomainSocketAddress} instances. 60 * It captures the file path name and reconstructs using the public static 61 * {@link #of(String) factory}. 62 * 63 * @serial include 64 */ 65 private static final class Ser implements Serializable { 66 @java.io.Serial 67 static final long serialVersionUID = -7955684448513979814L; 68 69 /** 70 * The path name. 71 * @serial 72 */ 73 private final String pathname; 74 75 Ser(String pathname) { 76 this.pathname = pathname; 77 } 78 79 /** 80 * Creates a {@link UnixDomainSocketAddress} instance, by an invocation 81 * of the {@link #of(String) factory} method passing the path name. 82 * @return a UnixDomainSocketAddress 83 */ 84 @java.io.Serial 85 private Object readResolve() { 86 return UnixDomainSocketAddress.of(pathname); 87 } 88 } 89 90 /** 91 * Returns a 92 * <a href="{@docRoot}/serialized-form.html#java.net.UnixDomainSocketAddress.Ser"> 93 * Ser</a> containing the path name of this instance. 94 * 95 * @return a {@link Ser} 96 * representing the path name of this instance 97 */ 98 @java.io.Serial 99 private Object writeReplace() throws ObjectStreamException { 100 return new Ser(path.toString()); 101 } 102 103 /** 104 * Throws InvalidObjectException, always. 105 * @param s the stream 106 * @throws java.io.InvalidObjectException always 107 */ 108 @java.io.Serial 109 private void readObject(java.io.ObjectInputStream s) 110 throws java.io.InvalidObjectException 111 { 112 throw new java.io.InvalidObjectException("Proxy required"); 113 } 114 115 /** 116 * Throws InvalidObjectException, always. 117 * @throws java.io.InvalidObjectException always 118 */ 119 @java.io.Serial 120 private void readObjectNoData() 121 throws java.io.InvalidObjectException 122 { 123 throw new java.io.InvalidObjectException("Proxy required"); 124 } 125 126 private UnixDomainSocketAddress(Path path) { 127 FileSystem fs = path.getFileSystem(); 128 if (fs != FileSystems.getDefault()) { 129 throw new IllegalArgumentException(); // fix message 130 } 131 if (fs.getClass().getModule() != Object.class.getModule()) { 132 throw new IllegalArgumentException(); // fix message 133 } 134 this.path = path; 135 } 136 137 /** 138 * Create a UnixDomainSocketAddress from the given path string. 139 * 140 * @param pathname 141 * The path string, which can be empty 142 * 143 * @return A UnixDomainSocketAddress 144 * 145 * @throws InvalidPathException 146 * If the path cannot be converted to a Path 147 */ 148 public static UnixDomainSocketAddress of(String pathname) { 149 return of(Path.of(pathname)); 150 } 151 152 /** 153 * Create a UnixDomainSocketAddress for the given path. 154 * 155 * @param path 156 * The path to the socket, which can be empty 157 * 158 * @return A UnixDomainSocketAddress 159 * 160 * @throws IllegalArgumentException 161 * If the path is not associated with the default file system 162 */ 163 public static UnixDomainSocketAddress of(Path path) { 164 return new UnixDomainSocketAddress(path); 165 } 166 167 /** 168 * Return this address's path. 169 * 170 * @return this address's path 171 */ 172 public Path getPath() { 173 return path; 174 } 175 176 /** 177 * Returns the hash code of this {@code UnixDomainSocketAddress} 178 */ 179 @Override 180 public int hashCode() { 181 return path.hashCode(); 182 } 183 184 /** 185 * Compares this address with another object. 186 * 187 * @return true if the path fields are equal 188 */ 189 @Override 190 public boolean equals(Object o) { 191 if (! (o instanceof UnixDomainSocketAddress)) 192 return false; 193 UnixDomainSocketAddress that = (UnixDomainSocketAddress)o; 194 return this.path.equals(that.path); 195 } 196 197 /** 198 * Returns a string representation of this {@code UnixDomainSocketAddress}. 199 * 200 * @return this address's path which may be empty for an unnamed address 201 */ 202 @Override 203 public String toString() { 204 return path.toString(); 205 } 206 }