View Javadoc
1   /*
2    * junixsocket
3    *
4    * Copyright 2009-2024 Christian Kohlschütter
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.newsclub.net.unix;
19  
20  import java.io.File;
21  import java.io.FileDescriptor;
22  import java.io.IOException;
23  import java.net.ServerSocket;
24  import java.net.SocketException;
25  import java.nio.file.Path;
26  
27  /**
28   * The server part of an AF_UNIX domain socket.
29   *
30   * @author Christian Kohlschütter
31   */
32  public final class AFUNIXServerSocket extends AFServerSocket<AFUNIXSocketAddress> {
33    /**
34     * Constructs a new, unconnected instance.
35     *
36     * @throws IOException if the operation fails.
37     */
38    protected AFUNIXServerSocket() throws IOException {
39      super();
40    }
41  
42    /**
43     * Constructs a new instance, optionally associated with the given file descriptor.
44     *
45     * @param fdObj The file descriptor, or {@code null}.
46     * @throws IOException if the operation fails.
47     */
48    AFUNIXServerSocket(FileDescriptor fdObj) throws IOException {
49      super(fdObj);
50    }
51  
52    @Override
53    protected AFUNIXServerSocketChannel newChannel() {
54      return new AFUNIXServerSocketChannel(this);
55    }
56  
57    @Override
58    public AFUNIXServerSocketChannel getChannel() {
59      return (AFUNIXServerSocketChannel) super.getChannel();
60    }
61  
62    /**
63     * Returns a new, unbound AF_UNIX {@link ServerSocket}.
64     *
65     * @return The new, unbound {@link AFServerSocket}.
66     * @throws IOException if the operation fails.
67     */
68    public static AFUNIXServerSocket newInstance() throws IOException {
69      return (AFUNIXServerSocket) AFServerSocket.newInstance(AFUNIXServerSocket::new);
70    }
71  
72    static AFUNIXServerSocket newInstance(FileDescriptor fdObj, int localPort, int remotePort)
73        throws IOException {
74      return (AFUNIXServerSocket) AFServerSocket.newInstance(AFUNIXServerSocket::new, fdObj,
75          localPort, remotePort);
76    }
77  
78    /**
79     * Returns a new AF_UNIX {@link ServerSocket} that is bound to the given
80     * {@link AFUNIXSocketAddress}.
81     *
82     * @param addr The socket file to bind to.
83     * @return The new, bound {@link AFServerSocket}.
84     * @throws IOException if the operation fails.
85     */
86    public static AFUNIXServerSocket bindOn(final AFUNIXSocketAddress addr) throws IOException {
87      return (AFUNIXServerSocket) AFServerSocket.bindOn(AFUNIXServerSocket::new, addr);
88    }
89  
90    /**
91     * Returns a new AF_UNIX {@link ServerSocket} that is bound to the given {@link AFSocketAddress}.
92     *
93     * @param addr The socket file to bind to.
94     * @param deleteOnClose If {@code true}, the socket file (if the address points to a file) will be
95     *          deleted upon {@link #close}.
96     * @return The new, bound {@link AFServerSocket}.
97     * @throws IOException if the operation fails.
98     */
99    public static AFUNIXServerSocket bindOn(final AFUNIXSocketAddress addr, boolean deleteOnClose)
100       throws IOException {
101     return (AFUNIXServerSocket) AFServerSocket.bindOn(AFUNIXServerSocket::new, addr, deleteOnClose);
102   }
103 
104   /**
105    * Returns a new AF_UNIX {@link ServerSocket} that is bound to the given path.
106    *
107    * @param path The path to bind to.
108    * @param deleteOnClose If {@code true}, the socket file will be deleted upon {@link #close}.
109    * @return The new, bound {@link AFServerSocket}.
110    * @throws IOException if the operation fails.
111    */
112   public static AFUNIXServerSocket bindOn(final File path, boolean deleteOnClose)
113       throws IOException {
114     return bindOn(path.toPath(), deleteOnClose);
115   }
116 
117   /**
118    * Returns a new AF_UNIX {@link ServerSocket} that is bound to the given path.
119    *
120    * @param path The path to bind to.
121    * @param deleteOnClose If {@code true}, the socket file will be deleted upon {@link #close}.
122    * @return The new, bound {@link AFServerSocket}.
123    * @throws IOException if the operation fails.
124    */
125   public static AFUNIXServerSocket bindOn(final Path path, boolean deleteOnClose)
126       throws IOException {
127     return (AFUNIXServerSocket) AFServerSocket.bindOn(AFUNIXServerSocket::new, AFUNIXSocketAddress
128         .of(path), deleteOnClose);
129   }
130 
131   /**
132    * Returns a new, <em>unbound</em> AF_UNIX {@link ServerSocket} that will always bind to the given
133    * address, regardless of any socket address used in a call to <code>bind</code>.
134    *
135    * @param forceAddr The address to use.
136    * @return The new, yet unbound {@link AFServerSocket}.
137    * @throws IOException if an exception occurs.
138    */
139   public static AFUNIXServerSocket forceBindOn(final AFUNIXSocketAddress forceAddr)
140       throws IOException {
141     return (AFUNIXServerSocket) AFServerSocket.forceBindOn(AFUNIXServerSocket::new, forceAddr);
142   }
143 
144   @Override
145   protected AFSocketImpl<AFUNIXSocketAddress> newImpl(FileDescriptor fdObj) throws SocketException {
146     return new AFUNIXSocketImpl(fdObj);
147   }
148 
149   /**
150    * Returns a new {@link AFSocket} instance.
151    *
152    * @return The new instance.
153    * @throws IOException on error.
154    */
155   @Override
156   protected AFUNIXSocket newSocketInstance() throws IOException {
157     return AFUNIXSocket.newInstance();
158   }
159 
160   @Override
161   public AFUNIXSocket accept() throws IOException {
162     return (AFUNIXSocket) super.accept();
163   }
164 }