3333import java .net .InetSocketAddress ;
3434import java .net .SocketAddress ;
3535import java .net .StandardSocketOptions ;
36+ import java .net .UnixDomainSocketAddress ;
3637import java .nio .*;
3738import java .nio .channels .*;
3839import java .nio .file .Files ;
4445import java .security .SecureRandom ;
4546import java .util .Random ;
4647
48+ import static java .net .StandardProtocolFamily .UNIX ;
4749
4850/**
4951 * A simple Pipe implementation based on a socket connection.
@@ -67,12 +69,14 @@ private static class Initializer
6769 {
6870
6971 private final SelectorProvider sp ;
72+ private final boolean preferUnixDomain ;
7073 private IOException ioe ;
7174 SourceChannelImpl source ;
7275 SinkChannelImpl sink ;
7376
74- private Initializer (SelectorProvider sp ) {
77+ private Initializer (SelectorProvider sp , boolean preferUnixDomain ) {
7578 this .sp = sp ;
79+ this .preferUnixDomain = preferUnixDomain ;
7680 }
7781
7882 @ Override
@@ -120,7 +124,7 @@ public void run() {
120124 // Bind ServerSocketChannel to a port on the loopback
121125 // address
122126 if (ssc == null || !ssc .isOpen ()) {
123- ssc = createListener ();
127+ ssc = createListener (preferUnixDomain );
124128 sa = ssc .getLocalAddress ();
125129 }
126130
@@ -162,28 +166,34 @@ public void run() {
162166 try {
163167 if (ssc != null )
164168 ssc .close ();
169+ if (sa instanceof UnixDomainSocketAddress uaddr ) {
170+ Files .deleteIfExists (uaddr .getPath ());
171+ }
165172 } catch (IOException e2 ) {}
166173 }
167174 }
168175 }
169176 }
170177
171178 /**
172- * Creates a Pipe implementation that supports buffering.
179+ * Creates a (TCP) Pipe implementation that supports buffering.
173180 */
174181 PipeImpl (SelectorProvider sp ) throws IOException {
175- this (sp , true );
182+ this (sp , true , false );
176183 }
177184
178185 /**
179- * Creates Pipe implementation that supports optionally buffering.
186+ * Creates Pipe implementation that supports optionally buffering
187+ * and is TCP by default, but if Unix domain is supported and
188+ * preferAfUnix is true, then Unix domain sockets are used.
189+ *
190+ * @param preferAfUnix use Unix domain sockets if supported
180191 *
181- * @implNote Uses a loopback connection. When buffering is
182- * disabled then it sets TCP_NODELAY on the sink channel.
192+ * @param buffering if false set TCP_NODELAY on TCP sockets
183193 */
184194 @ SuppressWarnings ("removal" )
185- PipeImpl (SelectorProvider sp , boolean buffering ) throws IOException {
186- Initializer initializer = new Initializer (sp );
195+ PipeImpl (SelectorProvider sp , boolean preferAfUnix , boolean buffering ) throws IOException {
196+ Initializer initializer = new Initializer (sp , preferAfUnix );
187197 try {
188198 AccessController .doPrivileged (initializer );
189199 SinkChannelImpl sink = initializer .sink ;
@@ -205,8 +215,19 @@ public SinkChannelImpl sink() {
205215 return sink ;
206216 }
207217
208- private static ServerSocketChannel createListener () throws IOException {
209- ServerSocketChannel listener = ServerSocketChannel .open ();
218+ private static ServerSocketChannel createListener (boolean preferUnixDomain ) throws IOException {
219+ ServerSocketChannel listener = null ;
220+ if (preferUnixDomain && UnixDomainSockets .isSupported ()) {
221+ try {
222+ listener = ServerSocketChannel .open (UNIX );
223+ listener .bind (null );
224+ return listener ;
225+ } catch (IOException | UnsupportedOperationException e ) {
226+ if (listener != null )
227+ listener .close ();
228+ }
229+ }
230+ listener = ServerSocketChannel .open ();
210231 InetAddress lb = InetAddress .getLoopbackAddress ();
211232 listener .bind (new InetSocketAddress (lb , 0 ));
212233 return listener ;
0 commit comments