Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/nio/ch/InheritedChannel.java
32288 views
1
/*
2
* Copyright (c) 2003, 2013, 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 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.
53
* In order to reduce the possibility of an error at close time we
54
* open /dev/null early - that way we know we won't run out of file
55
* descriptors at close time. This makes the close operation a
56
* simple dup2 operation for each of the standard streams.
57
*/
58
private static int devnull = -1;
59
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
}
101
102
protected void implCloseSelectableChannel() throws IOException {
103
super.implCloseSelectableChannel();
104
detachIOStreams();
105
}
106
107
}
108
109
public static class InheritedDatagramChannelImpl extends
110
DatagramChannelImpl {
111
112
InheritedDatagramChannelImpl(SelectorProvider sp,
113
FileDescriptor fd)
114
throws IOException
115
{
116
super(sp, fd);
117
}
118
119
protected void implCloseSelectableChannel() throws IOException {
120
super.implCloseSelectableChannel();
121
detachIOStreams();
122
}
123
}
124
125
/*
126
* If there's a SecurityManager then check for the appropriate
127
* RuntimePermission.
128
*/
129
private static void checkAccess(Channel c) {
130
SecurityManager sm = System.getSecurityManager();
131
if (sm != null) {
132
sm.checkPermission(
133
new RuntimePermission("inheritedChannel")
134
);
135
}
136
}
137
138
139
/*
140
* If standard inherited channel is connected to a socket then return a Channel
141
* of the appropriate type based standard input.
142
*/
143
private static Channel createChannel() throws IOException {
144
145
// dup the file descriptor - we do this so that for two reasons :-
146
// 1. Avoids any timing issues with FileDescriptor.in being closed
147
// or redirected while we create the channel.
148
// 2. Allows streams based on file descriptor 0 to co-exist with
149
// the channel (closing one doesn't impact the other)
150
151
int fdVal = dup(0);
152
153
// Examine the file descriptor - if it's not a socket then we don't
154
// create a channel so we release the file descriptor.
155
156
int st;
157
st = soType0(fdVal);
158
if (st != SOCK_STREAM && st != SOCK_DGRAM) {
159
close0(fdVal);
160
return null;
161
}
162
163
164
// Next we create a FileDescriptor for the dup'ed file descriptor
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[] = { new Integer(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
213
if (!haveChannel) {
214
channel = createChannel();
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 int dup(int fd) throws IOException;
230
private static native void dup2(int fd, int fd2) throws IOException;
231
private static native int open0(String path, int oflag) throws IOException;
232
private static native void close0(int fd) throws IOException;
233
private static native int soType0(int fd);
234
private static native InetAddress peerAddress0(int fd);
235
private static native int peerPort0(int fd);
236
237
static {
238
IOUtil.load();
239
}
240
}
241
242