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