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 sun.nio.ch;
27
28 import java.lang.reflect.Constructor;
29 import java.io.FileDescriptor;
30 import java.io.IOException;
31 import java.net.InetAddress;
32 import java.net.InetSocketAddress;
33 import java.nio.channels.Channel;
34 import java.nio.channels.SocketChannel;
35 import java.nio.channels.ServerSocketChannel;
36 import java.nio.channels.DatagramChannel;
37 import java.nio.channels.spi.SelectorProvider;
38
39 class InheritedChannel {
40
41 // the "types" of socket returned by soType0
42 private static final int UNKNOWN = -1;
43 private static final int SOCK_STREAM = 1;
44 private static final int SOCK_DGRAM = 2;
45
46 // oflag values when opening a file
47 private static final int O_RDONLY = 0;
48 private static final int O_WRONLY = 1;
49 private static final int O_RDWR = 2;
50
51 /*
52 * In order to "detach" the standard streams we dup them to /dev/null.
60 private static void detachIOStreams() {
61 try {
62 dup2(devnull, 0);
63 dup2(devnull, 1);
64 dup2(devnull, 2);
65 } catch (IOException ioe) {
66 // this shouldn't happen
67 throw new InternalError(ioe);
68 }
69 }
70
71 /*
72 * Override the implCloseSelectableChannel for each channel type - this
73 * allows us to "detach" the standard streams after closing and ensures
74 * that the underlying socket really closes.
75 */
76 public static class InheritedSocketChannelImpl extends SocketChannelImpl {
77
78 InheritedSocketChannelImpl(SelectorProvider sp,
79 FileDescriptor fd,
80 InetSocketAddress remote)
81 throws IOException
82 {
83 super(sp, fd, remote);
84 }
85
86 protected void implCloseSelectableChannel() throws IOException {
87 super.implCloseSelectableChannel();
88 detachIOStreams();
89 }
90 }
91
92 public static class InheritedServerSocketChannelImpl extends
93 ServerSocketChannelImpl {
94
95 InheritedServerSocketChannelImpl(SelectorProvider sp,
96 FileDescriptor fd)
97 throws IOException
98 {
99 super(sp, fd, true);
100 }
165 // Have to use reflection and also make assumption on how FD
166 // is implemented.
167
168 Class<?> paramTypes[] = { int.class };
169 Constructor<?> ctr = Reflect.lookupConstructor("java.io.FileDescriptor",
170 paramTypes);
171 Object args[] = { Integer.valueOf(fdVal) };
172 FileDescriptor fd = (FileDescriptor)Reflect.invoke(ctr, args);
173
174
175 // Now create the channel. If the socket is a streams socket then
176 // we see if tthere is a peer (ie: connected). If so, then we
177 // create a SocketChannel, otherwise a ServerSocketChannel.
178 // If the socket is a datagram socket then create a DatagramChannel
179
180 SelectorProvider provider = SelectorProvider.provider();
181 assert provider instanceof sun.nio.ch.SelectorProviderImpl;
182
183 Channel c;
184 if (st == SOCK_STREAM) {
185 InetAddress ia = peerAddress0(fdVal);
186 if (ia == null) {
187 c = new InheritedServerSocketChannelImpl(provider, fd);
188 } else {
189 int port = peerPort0(fdVal);
190 assert port > 0;
191 InetSocketAddress isa = new InetSocketAddress(ia, port);
192 c = new InheritedSocketChannelImpl(provider, fd, isa);
193 }
194 } else {
195 c = new InheritedDatagramChannelImpl(provider, fd);
196 }
197 return c;
198 }
199
200 private static boolean haveChannel = false;
201 private static Channel channel = null;
202
203 /*
204 * Returns a Channel representing the inherited channel if the
205 * inherited channel is a stream connected to a network socket.
206 */
207 public static synchronized Channel getChannel() throws IOException {
208 if (devnull < 0) {
209 devnull = open0("/dev/null", O_RDWR);
210 }
211
212 // If we don't have the channel try to create it
215 haveChannel = true;
216 }
217
218 // if there is a channel then do the security check before
219 // returning it.
220 if (channel != null) {
221 checkAccess(channel);
222 }
223 return channel;
224 }
225
226
227 // -- Native methods --
228
229 private static native void initIDs();
230 private static native int dup(int fd) throws IOException;
231 private static native void dup2(int fd, int fd2) throws IOException;
232 private static native int open0(String path, int oflag) throws IOException;
233 private static native void close0(int fd) throws IOException;
234 private static native int soType0(int fd);
235 private static native InetAddress peerAddress0(int fd);
236 private static native int peerPort0(int fd);
237
238 static {
239 IOUtil.load();
240 initIDs();
241 }
242 }
|
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 sun.nio.ch;
27
28 import java.lang.reflect.Constructor;
29 import java.io.FileDescriptor;
30 import java.io.IOException;
31 import java.net.InetAddress;
32 import java.net.InetSocketAddress;
33 import java.net.SocketAddress;
34 import java.net.UnixSocketAddress;
35 import java.nio.channels.Channel;
36 import java.nio.channels.SocketChannel;
37 import java.nio.channels.ServerSocketChannel;
38 import java.nio.channels.DatagramChannel;
39 import java.nio.channels.spi.SelectorProvider;
40
41 class InheritedChannel {
42
43 // the "types" of socket returned by soType0
44 private static final int UNKNOWN = -1;
45 private static final int SOCK_STREAM = 1;
46 private static final int SOCK_DGRAM = 2;
47
48 // oflag values when opening a file
49 private static final int O_RDONLY = 0;
50 private static final int O_WRONLY = 1;
51 private static final int O_RDWR = 2;
52
53 /*
54 * In order to "detach" the standard streams we dup them to /dev/null.
62 private static void detachIOStreams() {
63 try {
64 dup2(devnull, 0);
65 dup2(devnull, 1);
66 dup2(devnull, 2);
67 } catch (IOException ioe) {
68 // this shouldn't happen
69 throw new InternalError(ioe);
70 }
71 }
72
73 /*
74 * Override the implCloseSelectableChannel for each channel type - this
75 * allows us to "detach" the standard streams after closing and ensures
76 * that the underlying socket really closes.
77 */
78 public static class InheritedSocketChannelImpl extends SocketChannelImpl {
79
80 InheritedSocketChannelImpl(SelectorProvider sp,
81 FileDescriptor fd,
82 SocketAddress remote)
83 throws IOException
84 {
85 super(sp, fd, remote);
86 }
87
88 protected void implCloseSelectableChannel() throws IOException {
89 super.implCloseSelectableChannel();
90 detachIOStreams();
91 }
92 }
93
94 public static class InheritedServerSocketChannelImpl extends
95 ServerSocketChannelImpl {
96
97 InheritedServerSocketChannelImpl(SelectorProvider sp,
98 FileDescriptor fd)
99 throws IOException
100 {
101 super(sp, fd, true);
102 }
167 // Have to use reflection and also make assumption on how FD
168 // is implemented.
169
170 Class<?> paramTypes[] = { int.class };
171 Constructor<?> ctr = Reflect.lookupConstructor("java.io.FileDescriptor",
172 paramTypes);
173 Object args[] = { Integer.valueOf(fdVal) };
174 FileDescriptor fd = (FileDescriptor)Reflect.invoke(ctr, args);
175
176
177 // Now create the channel. If the socket is a streams socket then
178 // we see if tthere is a peer (ie: connected). If so, then we
179 // create a SocketChannel, otherwise a ServerSocketChannel.
180 // If the socket is a datagram socket then create a DatagramChannel
181
182 SelectorProvider provider = SelectorProvider.provider();
183 assert provider instanceof sun.nio.ch.SelectorProviderImpl;
184
185 Channel c;
186 if (st == SOCK_STREAM) {
187 SocketAddress sa = peerAddress0(fdVal);
188 if (sa == null) {
189 c = new InheritedServerSocketChannelImpl(provider, fd);
190 } else if (sa instanceof InetSocketAddress) {
191 c = new InheritedSocketChannelImpl(provider, fd, sa);
192 } else if (sa instanceof UnixSocketAddress) {
193 // TODO: custom class for unix sockets
194 c = new InheritedSocketChannelImpl(provider, fd, sa);
195 } else {
196 throw new IllegalStateException("Unsupported socket type: " + sa.getClass().getName());
197 }
198 } else {
199 c = new InheritedDatagramChannelImpl(provider, fd);
200 }
201 return c;
202 }
203
204 private static boolean haveChannel = false;
205 private static Channel channel = null;
206
207 /*
208 * Returns a Channel representing the inherited channel if the
209 * inherited channel is a stream connected to a network socket.
210 */
211 public static synchronized Channel getChannel() throws IOException {
212 if (devnull < 0) {
213 devnull = open0("/dev/null", O_RDWR);
214 }
215
216 // If we don't have the channel try to create it
219 haveChannel = true;
220 }
221
222 // if there is a channel then do the security check before
223 // returning it.
224 if (channel != null) {
225 checkAccess(channel);
226 }
227 return channel;
228 }
229
230
231 // -- Native methods --
232
233 private static native void initIDs();
234 private static native int dup(int fd) throws IOException;
235 private static native void dup2(int fd, int fd2) throws IOException;
236 private static native int open0(String path, int oflag) throws IOException;
237 private static native void close0(int fd) throws IOException;
238 private static native int soType0(int fd);
239 private static native SocketAddress peerAddress0(int fd);
240
241 static {
242 IOUtil.load();
243 initIDs();
244 }
245 }
|