Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.jdi/share/classes/com/sun/tools/jdi/AbstractLauncher.java
41161 views
1
/*
2
* Copyright (c) 1999, 2017, 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 com.sun.tools.jdi;
27
28
import java.io.IOException;
29
import java.io.InterruptedIOException;
30
import java.util.ArrayList;
31
import java.util.List;
32
import java.util.Map;
33
import java.util.StringTokenizer;
34
35
import com.sun.jdi.Bootstrap;
36
import com.sun.jdi.InternalException;
37
import com.sun.jdi.VirtualMachine;
38
import com.sun.jdi.VirtualMachineManager;
39
import com.sun.jdi.connect.Connector;
40
import com.sun.jdi.connect.IllegalConnectorArgumentsException;
41
import com.sun.jdi.connect.LaunchingConnector;
42
import com.sun.jdi.connect.VMStartException;
43
import com.sun.jdi.connect.spi.Connection;
44
import com.sun.jdi.connect.spi.TransportService;
45
46
abstract class AbstractLauncher extends ConnectorImpl
47
implements LaunchingConnector
48
{
49
abstract public VirtualMachine
50
launch(Map<String, ? extends Connector.Argument> arguments)
51
throws IOException, IllegalConnectorArgumentsException,
52
VMStartException;
53
54
abstract public String name();
55
56
abstract public String description();
57
58
ThreadGroup grp;
59
60
AbstractLauncher() {
61
super();
62
63
grp = Thread.currentThread().getThreadGroup();
64
ThreadGroup parent = null;
65
while ((parent = grp.getParent()) != null) {
66
grp = parent;
67
}
68
}
69
70
String[] tokenizeCommand(String command, char quote) {
71
String quoteStr = String.valueOf(quote); // easier to deal with
72
73
/*
74
* Tokenize the command, respecting the given quote character.
75
*/
76
StringTokenizer tokenizer = new StringTokenizer(command,
77
quote + " \t\r\n\f",
78
true);
79
String quoted = null;
80
String pending = null;
81
List<String> tokenList = new ArrayList<>();
82
while (tokenizer.hasMoreTokens()) {
83
String token = tokenizer.nextToken();
84
if (quoted != null) {
85
if (token.equals(quoteStr)) {
86
tokenList.add(quoted);
87
quoted = null;
88
} else {
89
quoted += token;
90
}
91
} else if (pending != null) {
92
if (token.equals(quoteStr)) {
93
quoted = pending;
94
} else if ((token.length() == 1) &&
95
Character.isWhitespace(token.charAt(0))) {
96
tokenList.add(pending);
97
} else {
98
throw new InternalException("Unexpected token: " + token);
99
}
100
pending = null;
101
} else {
102
if (token.equals(quoteStr)) {
103
quoted = "";
104
} else if ((token.length() == 1) &&
105
Character.isWhitespace(token.charAt(0))) {
106
// continue
107
} else {
108
pending = token;
109
}
110
}
111
}
112
113
/*
114
* Add final token.
115
*/
116
if (pending != null) {
117
tokenList.add(pending);
118
}
119
120
/*
121
* An unclosed quote at the end of the command. Do an
122
* implicit end quote.
123
*/
124
if (quoted != null) {
125
tokenList.add(quoted);
126
}
127
128
String[] tokenArray = new String[tokenList.size()];
129
for (int i = 0; i < tokenList.size(); i++) {
130
tokenArray[i] = tokenList.get(i);
131
}
132
return tokenArray;
133
}
134
135
protected VirtualMachine launch(String[] commandArray, String address,
136
TransportService.ListenKey listenKey,
137
TransportService ts)
138
throws IOException, VMStartException {
139
Helper helper = new Helper(commandArray, address, listenKey, ts);
140
helper.launchAndAccept();
141
142
VirtualMachineManager manager =
143
Bootstrap.virtualMachineManager();
144
145
return manager.createVirtualMachine(helper.connection(),
146
helper.process());
147
}
148
149
/**
150
* This class simply provides a context for a single launch and
151
* accept. It provides instance fields that can be used by
152
* all threads involved. This stuff can't be in the Connector proper
153
* because the connector is a singleton and is not specific to any
154
* one launch.
155
*/
156
private class Helper {
157
@SuppressWarnings("unused")
158
private final String address;
159
private TransportService.ListenKey listenKey;
160
private TransportService ts;
161
private final String[] commandArray;
162
private Process process = null;
163
private Connection connection = null;
164
private IOException acceptException = null;
165
private boolean exited = false;
166
167
Helper(String[] commandArray, String address, TransportService.ListenKey listenKey,
168
TransportService ts) {
169
this.commandArray = commandArray;
170
this.address = address;
171
this.listenKey = listenKey;
172
this.ts = ts;
173
}
174
175
String commandString() {
176
String str = "";
177
for (int i = 0; i < commandArray.length; i++) {
178
if (i > 0) {
179
str += " ";
180
}
181
str += commandArray[i];
182
}
183
return str;
184
}
185
186
synchronized void launchAndAccept() throws
187
IOException, VMStartException {
188
189
process = Runtime.getRuntime().exec(commandArray);
190
191
Thread acceptingThread = acceptConnection();
192
Thread monitoringThread = monitorTarget();
193
try {
194
while ((connection == null) &&
195
(acceptException == null) &&
196
!exited) {
197
wait();
198
}
199
200
if (exited) {
201
throw new VMStartException(
202
"VM initialization failed for: " + commandString(), process);
203
}
204
if (acceptException != null) {
205
// Rethrow the exception in this thread
206
throw acceptException;
207
}
208
} catch (InterruptedException e) {
209
throw new InterruptedIOException("Interrupted during accept");
210
} finally {
211
acceptingThread.interrupt();
212
monitoringThread.interrupt();
213
}
214
}
215
216
Process process() {
217
return process;
218
}
219
220
Connection connection() {
221
return connection;
222
}
223
224
synchronized void notifyOfExit() {
225
exited = true;
226
notify();
227
}
228
229
synchronized void notifyOfConnection(Connection connection) {
230
this.connection = connection;
231
notify();
232
}
233
234
synchronized void notifyOfAcceptException(IOException acceptException) {
235
this.acceptException = acceptException;
236
notify();
237
}
238
239
Thread monitorTarget() {
240
Thread thread = new Thread(grp, "launched target monitor") {
241
public void run() {
242
try {
243
process.waitFor();
244
/*
245
* Notify waiting thread of VM error termination
246
*/
247
notifyOfExit();
248
} catch (InterruptedException e) {
249
// Connection has been established, stop monitoring
250
}
251
}
252
};
253
thread.setDaemon(true);
254
thread.start();
255
return thread;
256
}
257
258
Thread acceptConnection() {
259
Thread thread = new Thread(grp, "connection acceptor") {
260
public void run() {
261
try {
262
Connection connection = ts.accept(listenKey, 0, 0);
263
/*
264
* Notify waiting thread of connection
265
*/
266
notifyOfConnection(connection);
267
} catch (InterruptedIOException e) {
268
// VM terminated, stop accepting
269
} catch (IOException e) {
270
// Report any other exception to waiting thread
271
notifyOfAcceptException(e);
272
}
273
}
274
};
275
thread.setDaemon(true);
276
thread.start();
277
return thread;
278
}
279
}
280
}
281
282