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 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 class _ProcessStartStatus { | 169 class _ProcessStartStatus { |
170 int _errorCode; // Set to OS error code if process start failed. | 170 int _errorCode; // Set to OS error code if process start failed. |
171 String _errorMessage; // Set to OS error message if process start failed. | 171 String _errorMessage; // Set to OS error message if process start failed. |
172 } | 172 } |
173 | 173 |
174 | 174 |
175 // The NativeFieldWrapperClass1 can not be used with a mixin, due to missing | 175 // The NativeFieldWrapperClass1 can not be used with a mixin, due to missing |
176 // implicit constructor. | 176 // implicit constructor. |
177 class _ProcessImplNativeWrapper extends NativeFieldWrapperClass1 {} | 177 class _ProcessImplNativeWrapper extends NativeFieldWrapperClass1 {} |
178 | 178 |
179 class _ProcessImpl extends _ProcessImplNativeWrapper with _ServiceObject | 179 class _ProcessImpl extends _ProcessImplNativeWrapper implements Process { |
180 implements Process { | 180 _ProcessResourceInfo _resourceInfo; |
181 // Use default Map so we keep order. | 181 static bool connectedResourceHandler = false; |
182 static Map<int, _ProcessImpl> _processes = new Map<int, _ProcessImpl>(); | |
183 | 182 |
184 _ProcessImpl(String path, | 183 _ProcessImpl(String path, |
185 List<String> arguments, | 184 List<String> arguments, |
186 String this._workingDirectory, | 185 String this._workingDirectory, |
187 Map<String, String> environment, | 186 Map<String, String> environment, |
188 bool includeParentEnvironment, | 187 bool includeParentEnvironment, |
189 bool runInShell, | 188 bool runInShell, |
190 ProcessStartMode mode) : super() { | 189 ProcessStartMode mode) : super() { |
191 _processes[_serviceId] = this; | 190 if (!connectedResourceHandler) { |
| 191 registerExtension('__getProcesses', |
| 192 _ProcessResourceInfo.getStartedProcesses); |
| 193 registerExtension('__getProcessById', |
| 194 _ProcessResourceInfo.getProcessInfoMapById); |
| 195 connectedResourceHandler = true; |
| 196 } |
| 197 |
192 if (runInShell) { | 198 if (runInShell) { |
193 arguments = _getShellArguments(path, arguments); | 199 arguments = _getShellArguments(path, arguments); |
194 path = _getShellCommand(); | 200 path = _getShellCommand(); |
195 } | 201 } |
196 | 202 |
197 if (path is !String) { | 203 if (path is !String) { |
198 throw new ArgumentError("Path is not a String: $path"); | 204 throw new ArgumentError("Path is not a String: $path"); |
199 } | 205 } |
200 _path = path; | 206 _path = path; |
201 | 207 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 _stderr = new _StdStream(new _Socket._readPipe()); | 266 _stderr = new _StdStream(new _Socket._readPipe()); |
261 _stderr._stream._owner = this; | 267 _stderr._stream._owner = this; |
262 } | 268 } |
263 if (mode == ProcessStartMode.NORMAL) { | 269 if (mode == ProcessStartMode.NORMAL) { |
264 _exitHandler = new _Socket._readPipe(); | 270 _exitHandler = new _Socket._readPipe(); |
265 } | 271 } |
266 _ended = false; | 272 _ended = false; |
267 _started = false; | 273 _started = false; |
268 } | 274 } |
269 | 275 |
270 String get _serviceTypePath => 'io/processes'; | |
271 String get _serviceTypeName => 'Process'; | |
272 | |
273 Map _toJSON(bool ref) { | |
274 var r = { | |
275 'id': _servicePath, | |
276 'type': _serviceType(ref), | |
277 'name': '$_path', | |
278 'user_name': '$_path', | |
279 'pid': '$pid', | |
280 'arguments': _arguments.join(' '), | |
281 }; | |
282 if (ref) { | |
283 return r; | |
284 } | |
285 r['started'] = _started; | |
286 r['ended'] = _ended; | |
287 r['path'] = _path; | |
288 r['environment'] = _environment; | |
289 r['workingDirectory'] = _workingDirectory == null ? '.' : _workingDirectory; | |
290 if (_stdin._sink._nativeSocket.owner != null) { | |
291 r['stdin'] = _stdin._sink._nativeSocket._toJSON(true); | |
292 } | |
293 if (_stdout._stream._nativeSocket.owner != null) { | |
294 r['stdout'] = _stdout._stream._nativeSocket._toJSON(true); | |
295 } | |
296 if (_stderr._stream._nativeSocket.owner != null) { | |
297 r['stderr'] = _stderr._stream._nativeSocket._toJSON(true); | |
298 } | |
299 return r; | |
300 } | |
301 | |
302 static String _getShellCommand() { | 276 static String _getShellCommand() { |
303 if (Platform.isWindows) { | 277 if (Platform.isWindows) { |
304 return 'cmd.exe'; | 278 return 'cmd.exe'; |
305 } | 279 } |
306 return '/bin/sh'; | 280 return '/bin/sh'; |
307 } | 281 } |
308 | 282 |
309 static List<String> _getShellArguments(String executable, | 283 static List<String> _getShellArguments(String executable, |
310 List<String> arguments) { | 284 List<String> arguments) { |
311 List<String> shellArguments = []; | 285 List<String> shellArguments = []; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 if (!success) { | 385 if (!success) { |
412 completer.completeError( | 386 completer.completeError( |
413 new ProcessException(_path, | 387 new ProcessException(_path, |
414 _arguments, | 388 _arguments, |
415 status._errorMessage, | 389 status._errorMessage, |
416 status._errorCode)); | 390 status._errorCode)); |
417 return; | 391 return; |
418 } | 392 } |
419 | 393 |
420 _started = true; | 394 _started = true; |
| 395 _resourceInfo = new _ProcessResourceInfo(this); |
421 | 396 |
422 // Setup an exit handler to handle internal cleanup and possible | 397 // Setup an exit handler to handle internal cleanup and possible |
423 // callback when a process terminates. | 398 // callback when a process terminates. |
424 if (_mode == ProcessStartMode.NORMAL) { | 399 if (_mode == ProcessStartMode.NORMAL) { |
425 int exitDataRead = 0; | 400 int exitDataRead = 0; |
426 final int EXIT_DATA_SIZE = 8; | 401 final int EXIT_DATA_SIZE = 8; |
427 List<int> exitDataBuffer = new List<int>(EXIT_DATA_SIZE); | 402 List<int> exitDataBuffer = new List<int>(EXIT_DATA_SIZE); |
428 _exitHandler.listen((data) { | 403 _exitHandler.listen((data) { |
429 | 404 |
430 int exitCode(List<int> ints) { | 405 int exitCode(List<int> ints) { |
431 var code = _intFromBytes(ints, 0); | 406 var code = _intFromBytes(ints, 0); |
432 var negative = _intFromBytes(ints, 4); | 407 var negative = _intFromBytes(ints, 4); |
433 assert(negative == 0 || negative == 1); | 408 assert(negative == 0 || negative == 1); |
434 return (negative == 0) ? code : -code; | 409 return (negative == 0) ? code : -code; |
435 } | 410 } |
436 | 411 |
437 void handleExit() { | 412 void handleExit() { |
438 _ended = true; | 413 _ended = true; |
439 _exitCode.complete(exitCode(exitDataBuffer)); | 414 _exitCode.complete(exitCode(exitDataBuffer)); |
440 // Kill stdin, helping hand if the user forgot to do it. | 415 // Kill stdin, helping hand if the user forgot to do it. |
441 _stdin._sink.destroy(); | 416 _stdin._sink.destroy(); |
442 _processes.remove(_serviceId); | 417 _resourceInfo.stopped(); |
443 } | 418 } |
444 | 419 |
445 exitDataBuffer.setRange( | 420 exitDataBuffer.setRange( |
446 exitDataRead, exitDataRead + data.length, data); | 421 exitDataRead, exitDataRead + data.length, data); |
447 exitDataRead += data.length; | 422 exitDataRead += data.length; |
448 if (exitDataRead == EXIT_DATA_SIZE) { | 423 if (exitDataRead == EXIT_DATA_SIZE) { |
449 handleExit(); | 424 handleExit(); |
450 } | 425 } |
451 }); | 426 }); |
452 } | 427 } |
(...skipping 17 matching lines...) Expand all Loading... |
470 _stderr._stream._nativeSocket, | 445 _stderr._stream._nativeSocket, |
471 _exitHandler._nativeSocket, | 446 _exitHandler._nativeSocket, |
472 status); | 447 status); |
473 if (!success) { | 448 if (!success) { |
474 throw new ProcessException(_path, | 449 throw new ProcessException(_path, |
475 _arguments, | 450 _arguments, |
476 status._errorMessage, | 451 status._errorMessage, |
477 status._errorCode); | 452 status._errorCode); |
478 } | 453 } |
479 | 454 |
| 455 _resourceInfo = new _ProcessResourceInfo(this); |
| 456 |
480 var result = _wait( | 457 var result = _wait( |
481 _stdin._sink._nativeSocket, | 458 _stdin._sink._nativeSocket, |
482 _stdout._stream._nativeSocket, | 459 _stdout._stream._nativeSocket, |
483 _stderr._stream._nativeSocket, | 460 _stderr._stream._nativeSocket, |
484 _exitHandler._nativeSocket); | 461 _exitHandler._nativeSocket); |
485 | 462 |
486 getOutput(output, encoding) { | 463 getOutput(output, encoding) { |
487 if (encoding == null) return output; | 464 if (encoding == null) return output; |
488 return encoding.decode(output); | 465 return encoding.decode(output); |
489 } | 466 } |
490 | 467 |
491 _processes.remove(_serviceId); | 468 _resourceInfo.stopped(); |
492 | 469 |
493 return new ProcessResult( | 470 return new ProcessResult( |
494 result[0], | 471 result[0], |
495 result[1], | 472 result[1], |
496 getOutput(result[2], stdoutEncoding), | 473 getOutput(result[2], stdoutEncoding), |
497 getOutput(result[3], stderrEncoding)); | 474 getOutput(result[3], stderrEncoding)); |
498 } | 475 } |
499 | 476 |
500 bool _startNative(String path, | 477 bool _startNative(String path, |
501 List<String> arguments, | 478 List<String> arguments, |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 Encoding stderrEncoding) { | 595 Encoding stderrEncoding) { |
619 var process = new _ProcessImpl(executable, | 596 var process = new _ProcessImpl(executable, |
620 arguments, | 597 arguments, |
621 workingDirectory, | 598 workingDirectory, |
622 environment, | 599 environment, |
623 includeParentEnvironment, | 600 includeParentEnvironment, |
624 runInShell, | 601 runInShell, |
625 ProcessStartMode.NORMAL); | 602 ProcessStartMode.NORMAL); |
626 return process._runAndWait(stdoutEncoding, stderrEncoding); | 603 return process._runAndWait(stdoutEncoding, stderrEncoding); |
627 } | 604 } |
OLD | NEW |