1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.newsclub.net.unix;
19
20 import static java.util.Objects.requireNonNull;
21
22 import java.io.FileDescriptor;
23 import java.io.IOException;
24 import java.net.ProtocolFamily;
25 import java.net.ServerSocket;
26 import java.net.SocketAddress;
27 import java.net.SocketOption;
28 import java.net.StandardProtocolFamily;
29 import java.nio.channels.ServerSocketChannel;
30 import java.nio.channels.spi.SelectorProvider;
31 import java.util.Objects;
32 import java.util.Set;
33
34 import org.eclipse.jdt.annotation.NonNull;
35 import org.eclipse.jdt.annotation.Nullable;
36
37 import com.kohlschutter.annotations.compiletime.SuppressFBWarnings;
38
39
40
41
42
43
44
45 public abstract class AFServerSocketChannel<A extends AFSocketAddress> extends ServerSocketChannel
46 implements FileDescriptorAccess, AFSomeSocketChannel {
47 private final @NonNull AFServerSocket<A> afSocket;
48
49
50
51
52
53
54
55 @SuppressWarnings("all")
56 protected AFServerSocketChannel(AFServerSocket<A> socket, AFSelectorProvider<A> sp) {
57 super(sp);
58 this.afSocket = Objects.requireNonNull(socket);
59 }
60
61
62
63 @SuppressWarnings("unchecked")
64 @Override
65 public <T> T getOption(SocketOption<T> name) throws IOException {
66 if (name instanceof AFSocketOption<?>) {
67 return getAFCore().getOption((AFSocketOption<T>) name);
68 }
69 Integer optionId = SocketOptionsMapper.resolve(name);
70 if (optionId == null) {
71 throw new UnsupportedOperationException("unsupported option");
72 } else {
73 return (T) afSocket.getAFImpl().getOption(optionId);
74 }
75 }
76
77 @Override
78 public <T> AFServerSocketChannel<A> setOption(SocketOption<T> name, T value) throws IOException {
79 if (name instanceof AFSocketOption<?>) {
80 getAFCore().setOption((AFSocketOption<T>) name, value);
81 return this;
82 }
83 Integer optionId = SocketOptionsMapper.resolve(name);
84 if (optionId == null) {
85 throw new UnsupportedOperationException("unsupported option");
86 } else {
87 afSocket.getAFImpl().setOption(optionId, value);
88 }
89 return this;
90 }
91
92 @Override
93 public final Set<SocketOption<?>> supportedOptions() {
94 return SocketOptionsMapper.SUPPORTED_SOCKET_OPTIONS;
95 }
96
97
98
99 @Override
100 public final AFServerSocketChannel<A> bind(SocketAddress local, int backlog) throws IOException {
101 afSocket.bind(local, backlog);
102 return this;
103 }
104
105 @SuppressFBWarnings("EI_EXPOSE_REP")
106 @Override
107 public final AFServerSocket<A> socket() {
108 return afSocket;
109 }
110
111 @Override
112 public AFSocketChannel<A> accept() throws IOException {
113 boolean complete = false;
114 Exception exception = null;
115 try {
116 begin();
117 AFSocket<A> socket = afSocket.accept1(false);
118 complete = true;
119 return socket == null ? null : socket.getChannel();
120 } catch (IOException e) {
121 throw InterruptibleChannelUtil.ioExceptionOrThrowRuntimeException(
122 (exception = InterruptibleChannelUtil.handleException(this, e)));
123 } finally {
124 InterruptibleChannelUtil.endInterruptable(this, this::end, complete, exception);
125 }
126 }
127
128 @Override
129 public final @Nullable A getLocalAddress() {
130 return getLocalSocketAddress();
131 }
132
133 @Override
134 public final @Nullable A getLocalSocketAddress() {
135 return afSocket.getLocalSocketAddress();
136 }
137
138
139
140
141
142
143
144
145
146 public final boolean isLocalSocketAddressValid() {
147 return afSocket.isLocalSocketAddressValid();
148 }
149
150 @Override
151 protected final void implCloseSelectableChannel() throws IOException {
152 afSocket.close();
153 }
154
155 @Override
156 protected final void implConfigureBlocking(boolean block) throws IOException {
157 getAFCore().implConfigureBlocking(block);
158 }
159
160 final AFSocketCore getAFCore() {
161 return afSocket.getAFImpl().getCore();
162 }
163
164 @Override
165 public final FileDescriptor getFileDescriptor() throws IOException {
166 return afSocket.getFileDescriptor();
167 }
168
169
170
171
172
173
174
175
176
177 public final boolean isDeleteOnClose() {
178 return socket().isDeleteOnClose();
179 }
180
181
182
183
184
185
186
187
188
189
190 public final void setDeleteOnClose(boolean b) {
191 socket().setDeleteOnClose(b);
192 }
193
194 @Override
195 public void setShutdownOnClose(boolean enabled) {
196 socket().setShutdownOnClose(enabled);
197 }
198
199
200
201
202
203
204
205
206
207
208
209
210
211 public static ServerSocketChannel open(ProtocolFamily family) throws IOException {
212 requireNonNull(family);
213
214 if (family instanceof AFProtocolFamily) {
215 return ((AFProtocolFamily) family).openServerSocketChannel();
216 } else if ("UNIX".equals(family.name())) {
217 return AFUNIXServerSocketChannel.open();
218 } else if (family instanceof StandardProtocolFamily) {
219 return ServerSocketChannel.open();
220 } else {
221 throw new UnsupportedOperationException("Protocol family not supported");
222 }
223 }
224 }