OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 patch class _WindowsCodePageDecoder { | 5 patch class _WindowsCodePageDecoder { |
6 /* patch */ static String _decodeBytes(List<int> bytes) | 6 /* patch */ static String _decodeBytes(List<int> bytes) |
7 native "SystemEncodingToString"; | 7 native "SystemEncodingToString"; |
8 } | 8 } |
9 | 9 |
10 | 10 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 env.forEach((key, value) { | 83 env.forEach((key, value) { |
84 if (key is !String || value is !String) { | 84 if (key is !String || value is !String) { |
85 throw new ArgumentError( | 85 throw new ArgumentError( |
86 "Environment key or value is not a string: ($key, $value)"); | 86 "Environment key or value is not a string: ($key, $value)"); |
87 } | 87 } |
88 _environment.add('$key=$value'); | 88 _environment.add('$key=$value'); |
89 }); | 89 }); |
90 } | 90 } |
91 | 91 |
92 // stdin going to process. | 92 // stdin going to process. |
93 _stdin = new _Socket._writePipe(); | 93 _stdin = new _StdSink(new _Socket._writePipe()); |
94 // stdout coming from process. | 94 // stdout coming from process. |
95 _stdout = new _Socket._readPipe(); | 95 _stdout = new _StdStream(new _Socket._readPipe()); |
96 // stderr coming from process. | 96 // stderr coming from process. |
97 _stderr = new _Socket._readPipe(); | 97 _stderr = new _StdStream(new _Socket._readPipe()); |
98 _exitHandler = new _Socket._readPipe(); | 98 _exitHandler = new _Socket._readPipe(); |
99 _ended = false; | 99 _ended = false; |
100 _started = false; | 100 _started = false; |
101 } | 101 } |
102 | 102 |
103 String _windowsArgumentEscape(String argument) { | 103 String _windowsArgumentEscape(String argument) { |
104 var result = argument; | 104 var result = argument; |
105 if (argument.contains('\t') || argument.contains(' ')) { | 105 if (argument.contains('\t') || argument.contains(' ')) { |
106 // Produce something that the C runtime on Windows will parse | 106 // Produce something that the C runtime on Windows will parse |
107 // back as this string. | 107 // back as this string. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 Future<Process> _start() { | 156 Future<Process> _start() { |
157 var completer = new Completer(); | 157 var completer = new Completer(); |
158 // TODO(ager): Make the actual process starting really async instead of | 158 // TODO(ager): Make the actual process starting really async instead of |
159 // simulating it with a timer. | 159 // simulating it with a timer. |
160 Timer.run(() { | 160 Timer.run(() { |
161 var status = new _ProcessStartStatus(); | 161 var status = new _ProcessStartStatus(); |
162 bool success = _startNative(_path, | 162 bool success = _startNative(_path, |
163 _arguments, | 163 _arguments, |
164 _workingDirectory, | 164 _workingDirectory, |
165 _environment, | 165 _environment, |
166 _stdin._nativeSocket, | 166 _stdin._sink._nativeSocket, |
167 _stdout._nativeSocket, | 167 _stdout._stream._nativeSocket, |
168 _stderr._nativeSocket, | 168 _stderr._stream._nativeSocket, |
169 _exitHandler._nativeSocket, | 169 _exitHandler._nativeSocket, |
170 status); | 170 status); |
171 if (!success) { | 171 if (!success) { |
172 completer.completeError( | 172 completer.completeError( |
173 new ProcessException(_path, | 173 new ProcessException(_path, |
174 _arguments, | 174 _arguments, |
175 status._errorMessage, | 175 status._errorMessage, |
176 status._errorCode)); | 176 status._errorCode)); |
177 return; | 177 return; |
178 } | 178 } |
(...skipping 10 matching lines...) Expand all Loading... |
189 var code = _intFromBytes(ints, 0); | 189 var code = _intFromBytes(ints, 0); |
190 var negative = _intFromBytes(ints, 4); | 190 var negative = _intFromBytes(ints, 4); |
191 assert(negative == 0 || negative == 1); | 191 assert(negative == 0 || negative == 1); |
192 return (negative == 0) ? code : -code; | 192 return (negative == 0) ? code : -code; |
193 } | 193 } |
194 | 194 |
195 void handleExit() { | 195 void handleExit() { |
196 _ended = true; | 196 _ended = true; |
197 _exitCode.complete(exitCode(exitDataBuffer)); | 197 _exitCode.complete(exitCode(exitDataBuffer)); |
198 // Kill stdin, helping hand if the user forgot to do it. | 198 // Kill stdin, helping hand if the user forgot to do it. |
199 _stdin.destroy(); | 199 _stdin._sink.destroy(); |
200 } | 200 } |
201 | 201 |
202 exitDataBuffer.setRange(exitDataRead, data.length, data); | 202 exitDataBuffer.setRange(exitDataRead, data.length, data); |
203 exitDataRead += data.length; | 203 exitDataRead += data.length; |
204 if (exitDataRead == EXIT_DATA_SIZE) { | 204 if (exitDataRead == EXIT_DATA_SIZE) { |
205 handleExit(); | 205 handleExit(); |
206 } | 206 } |
207 }); | 207 }); |
208 | 208 |
209 completer.complete(this); | 209 completer.complete(this); |
210 }); | 210 }); |
211 return completer.future; | 211 return completer.future; |
212 } | 212 } |
213 | 213 |
214 bool _startNative(String path, | 214 bool _startNative(String path, |
215 List<String> arguments, | 215 List<String> arguments, |
216 String workingDirectory, | 216 String workingDirectory, |
217 List<String> environment, | 217 List<String> environment, |
218 _NativeSocket stdin, | 218 _NativeSocket stdin, |
219 _NativeSocket stdout, | 219 _NativeSocket stdout, |
220 _NativeSocket stderr, | 220 _NativeSocket stderr, |
221 _NativeSocket exitHandler, | 221 _NativeSocket exitHandler, |
222 _ProcessStartStatus status) native "Process_Start"; | 222 _ProcessStartStatus status) native "Process_Start"; |
223 | 223 |
224 Stream<List<int>> get stdout { | 224 Stream<List<int>> get stdout { |
225 // TODO(ajohnsen): Get stream object only. | |
226 return _stdout; | 225 return _stdout; |
227 } | 226 } |
228 | 227 |
229 Stream<List<int>> get stderr { | 228 Stream<List<int>> get stderr { |
230 // TODO(ajohnsen): Get stream object only. | |
231 return _stderr; | 229 return _stderr; |
232 } | 230 } |
233 | 231 |
234 IOSink get stdin { | 232 IOSink get stdin { |
235 // TODO(ajohnsen): Get consumer object only. | |
236 return _stdin; | 233 return _stdin; |
237 } | 234 } |
238 | 235 |
239 Future<int> get exitCode => _exitCode.future; | 236 Future<int> get exitCode => _exitCode.future; |
240 | 237 |
241 bool kill([ProcessSignal signal = ProcessSignal.SIGTERM]) { | 238 bool kill([ProcessSignal signal = ProcessSignal.SIGTERM]) { |
242 if (signal is! ProcessSignal) { | 239 if (signal is! ProcessSignal) { |
243 throw new ArgumentError( | 240 throw new ArgumentError( |
244 "Argument 'signal' must be a ProcessSignal"); | 241 "Argument 'signal' must be a ProcessSignal"); |
245 } | 242 } |
246 assert(_started); | 243 assert(_started); |
247 if (_ended) return false; | 244 if (_ended) return false; |
248 return _kill(this, signal._signalNumber); | 245 return _kill(this, signal._signalNumber); |
249 } | 246 } |
250 | 247 |
251 bool _kill(Process p, int signal) native "Process_Kill"; | 248 bool _kill(Process p, int signal) native "Process_Kill"; |
252 | 249 |
253 String _path; | 250 String _path; |
254 List<String> _arguments; | 251 List<String> _arguments; |
255 String _workingDirectory; | 252 String _workingDirectory; |
256 List<String> _environment; | 253 List<String> _environment; |
257 // Private methods of Socket are used by _in, _out, and _err. | 254 // Private methods of Socket are used by _in, _out, and _err. |
258 Socket _stdin; | 255 _StdSink _stdin; |
259 Socket _stdout; | 256 _StdStream _stdout; |
260 Socket _stderr; | 257 _StdStream _stderr; |
261 Socket _exitHandler; | 258 Socket _exitHandler; |
262 bool _ended; | 259 bool _ended; |
263 bool _started; | 260 bool _started; |
264 final Completer<int> _exitCode = new Completer<int>(); | 261 final Completer<int> _exitCode = new Completer<int>(); |
265 } | 262 } |
266 | 263 |
267 | 264 |
268 // _NonInteractiveProcess is a wrapper around an interactive process | 265 // _NonInteractiveProcess is a wrapper around an interactive process |
269 // that buffers output so it can be delivered when the process exits. | 266 // that buffers output so it can be delivered when the process exits. |
270 // _NonInteractiveProcess is used to implement the Process.run | 267 // _NonInteractiveProcess is used to implement the Process.run |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 | 324 |
328 class _ProcessResult implements ProcessResult { | 325 class _ProcessResult implements ProcessResult { |
329 const _ProcessResult(int this.exitCode, | 326 const _ProcessResult(int this.exitCode, |
330 String this.stdout, | 327 String this.stdout, |
331 String this.stderr); | 328 String this.stderr); |
332 | 329 |
333 final int exitCode; | 330 final int exitCode; |
334 final String stdout; | 331 final String stdout; |
335 final String stderr; | 332 final String stderr; |
336 } | 333 } |
OLD | NEW |