Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 _exit(int status) native "Exit"; | 5 _exit(int status) native "Exit"; |
| 6 | 6 |
| 7 class _ProcessStartStatus { | 7 class _ProcessStartStatus { |
| 8 int _errorCode; // Set to OS error code if process start failed. | 8 int _errorCode; // Set to OS error code if process start failed. |
| 9 String _errorMessage; // Set to OS error message if process start failed. | 9 String _errorMessage; // Set to OS error message if process start failed. |
| 10 } | 10 } |
| 11 | 11 |
| 12 | 12 |
| 13 class _Process extends NativeFieldWrapperClass1 implements Process { | 13 class _Process extends NativeFieldWrapperClass1 implements Process { |
| 14 static Future<ProcessResult> run(String path, | 14 static Future<ProcessResult> run(String path, |
| 15 List<String> arguments, | 15 List<String> arguments, |
| 16 [ProcessOptions options]) { | 16 [ProcessOptions options]) { |
| 17 return new _NonInteractiveProcess._start(path, arguments, options)._result; | 17 return new _NonInteractiveProcess(path, arguments, options)._result; |
| 18 } | 18 } |
| 19 | 19 |
| 20 _Process.start(String path, | 20 static Future<Process> start(String path, |
| 21 List<String> arguments, | 21 List<String> arguments, |
| 22 ProcessOptions options) { | 22 ProcessOptions options) { |
| 23 Completer completer = new Completer(); | |
| 24 _Process process = new _Process(path, arguments, options); | |
| 25 process._onStart = () { | |
| 26 process._onError = null; | |
| 27 completer.complete(process); | |
| 28 }; | |
| 29 process._onError = (e) { | |
| 30 process._onError = null; | |
| 31 completer.completeException(e); | |
| 32 }; | |
| 33 return completer.future; | |
| 34 } | |
| 35 | |
| 36 _Process(String path, List<String> arguments, ProcessOptions options) { | |
| 23 if (path is !String) { | 37 if (path is !String) { |
| 24 throw new ArgumentError("Path is not a String: $path"); | 38 throw new ArgumentError("Path is not a String: $path"); |
| 25 } | 39 } |
| 26 _path = path; | 40 _path = path; |
| 27 | 41 |
| 28 if (arguments is !List) { | 42 if (arguments is !List) { |
| 29 throw new ArgumentError("Arguments is not a List: $arguments"); | 43 throw new ArgumentError("Arguments is not a List: $arguments"); |
| 30 } | 44 } |
| 31 int len = arguments.length; | 45 int len = arguments.length; |
| 32 _arguments = new List<String>(len); | 46 _arguments = new List<String>(len); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 220 throw new ProcessException("Process closed"); | 234 throw new ProcessException("Process closed"); |
| 221 } | 235 } |
| 222 return _out.outputStream; | 236 return _out.outputStream; |
| 223 } | 237 } |
| 224 | 238 |
| 225 void kill([ProcessSignal signal = ProcessSignal.SIGTERM]) { | 239 void kill([ProcessSignal signal = ProcessSignal.SIGTERM]) { |
| 226 if (signal is! ProcessSignal) { | 240 if (signal is! ProcessSignal) { |
| 227 throw new ArgumentError( | 241 throw new ArgumentError( |
| 228 "Argument 'signal' must be a ProcessSignal"); | 242 "Argument 'signal' must be a ProcessSignal"); |
| 229 } | 243 } |
| 230 if (!_started) { | 244 assert(_started); |
| 231 var e = new ProcessException("Cannot kill process that is not started"); | 245 if (_ended) return; |
| 232 _reportError(e); | 246 if (_kill(this, signal._signalNumber)) return; |
| 233 return; | 247 throw new ProcessException("Could not kill process"); |
|
Anders Johnsen
2012/10/12 08:53:11
Maybe change exception to "Could not send kill sig
Mads Ager (google)
2012/10/12 08:56:25
And an error message about signals is not very Win
Anders Johnsen
2012/10/12 08:58:10
Hehe agreed, but if we mention both 'kill' and 'si
| |
| 234 } | |
| 235 if (_ended) { | |
| 236 return; | |
| 237 } | |
| 238 if (_kill(this, signal._signalNumber)) { | |
| 239 return; | |
| 240 } | |
| 241 _reportError(new ProcessException("Could not kill process")); | |
| 242 return; | |
| 243 } | 248 } |
| 244 | 249 |
| 245 bool _kill(Process p, int signal) native "Process_Kill"; | 250 bool _kill(Process p, int signal) native "Process_Kill"; |
| 246 | 251 |
| 247 void close() { | 252 void close() { |
| 248 if (_closed) { | 253 if (_closed) { |
| 249 throw new ProcessException("Process closed"); | 254 throw new ProcessException("Process closed"); |
| 250 } | 255 } |
| 251 _in.close(); | 256 _in.close(); |
| 252 _out.close(); | 257 _out.close(); |
| 253 _err.close(); | 258 _err.close(); |
| 254 _exitHandler.close(); | 259 _exitHandler.close(); |
| 255 _closed = true; | 260 _closed = true; |
| 256 } | 261 } |
| 257 | 262 |
| 258 void set onExit(void callback(int exitCode)) { | 263 void set onExit(void callback(int exitCode)) { |
| 259 if (_closed) { | 264 if (_closed) { |
| 260 throw new ProcessException("Process closed"); | 265 throw new ProcessException("Process closed"); |
| 261 } | 266 } |
| 262 if (_ended) { | 267 if (_ended) { |
| 263 throw new ProcessException("Process killed"); | 268 throw new ProcessException("Process killed"); |
| 264 } | 269 } |
| 265 _onExit = callback; | 270 _onExit = callback; |
| 266 } | 271 } |
| 267 | 272 |
| 268 void set onError(void callback(e)) { | |
| 269 _onError = callback; | |
| 270 } | |
| 271 | |
| 272 void set onStart(void callback()) { | |
| 273 _onStart = callback; | |
| 274 } | |
| 275 | |
| 276 void _reportError(e) { | 273 void _reportError(e) { |
|
Søren Gjesse
2012/10/12 11:44:04
This is not used any more - right?
Mads Ager (google)
2012/10/12 11:50:26
It is still used internally to report startup erro
| |
| 277 if (_onError != null) { | 274 if (_onError != null) { |
| 278 _onError(e); | 275 _onError(e); |
| 279 } else { | 276 } else { |
| 280 throw e; | 277 throw e; |
| 281 } | 278 } |
| 282 } | 279 } |
| 283 | 280 |
| 284 String _path; | 281 String _path; |
| 285 List<String> _arguments; | 282 List<String> _arguments; |
| 286 String _workingDirectory; | 283 String _workingDirectory; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 297 Function _onError; | 294 Function _onError; |
| 298 Function _onStart; | 295 Function _onStart; |
| 299 } | 296 } |
| 300 | 297 |
| 301 | 298 |
| 302 // _NonInteractiveProcess is a wrapper around an interactive process | 299 // _NonInteractiveProcess is a wrapper around an interactive process |
| 303 // that buffers output so it can be delivered when the process exits. | 300 // that buffers output so it can be delivered when the process exits. |
| 304 // _NonInteractiveProcess is used to implement the Process.run | 301 // _NonInteractiveProcess is used to implement the Process.run |
| 305 // method. | 302 // method. |
| 306 class _NonInteractiveProcess { | 303 class _NonInteractiveProcess { |
| 307 _NonInteractiveProcess._start(String path, | 304 _NonInteractiveProcess(String path, |
| 308 List<String> arguments, | 305 List<String> arguments, |
| 309 ProcessOptions options) { | 306 ProcessOptions options) { |
| 310 _completer = new Completer<ProcessResult>(); | 307 _completer = new Completer<ProcessResult>(); |
| 311 // Extract output encoding options and verify arguments. | 308 // Extract output encoding options and verify arguments. |
| 312 var stdoutEncoding = Encoding.UTF_8; | 309 var stdoutEncoding = Encoding.UTF_8; |
| 313 var stderrEncoding = Encoding.UTF_8; | 310 var stderrEncoding = Encoding.UTF_8; |
| 314 if (options !== null) { | 311 if (options !== null) { |
| 315 if (options.stdoutEncoding !== null) { | 312 if (options.stdoutEncoding !== null) { |
| 316 stdoutEncoding = options.stdoutEncoding; | 313 stdoutEncoding = options.stdoutEncoding; |
| 317 if (stdoutEncoding is !Encoding) { | 314 if (stdoutEncoding is !Encoding) { |
| 318 throw new ArgumentError( | 315 throw new ArgumentError( |
| 319 'stdoutEncoding option is not an encoding: $stdoutEncoding'); | 316 'stdoutEncoding option is not an encoding: $stdoutEncoding'); |
| 320 } | 317 } |
| 321 } | 318 } |
| 322 if (options.stderrEncoding !== null) { | 319 if (options.stderrEncoding !== null) { |
| 323 stderrEncoding = options.stderrEncoding; | 320 stderrEncoding = options.stderrEncoding; |
| 324 if (stderrEncoding is !Encoding) { | 321 if (stderrEncoding is !Encoding) { |
| 325 throw new ArgumentError( | 322 throw new ArgumentError( |
| 326 'stderrEncoding option is not an encoding: $stderrEncoding'); | 323 'stderrEncoding option is not an encoding: $stderrEncoding'); |
| 327 } | 324 } |
| 328 } | 325 } |
| 329 } | 326 } |
| 330 | 327 |
| 331 // Start the underlying process. | 328 // Start the underlying process. |
| 332 _process = new _Process.start(path, arguments, options); | 329 _process = new _Process(path, arguments, options); |
| 333 | 330 |
| 334 // Make sure stdin is closed. | 331 // Make sure stdin is closed. |
| 335 _process.onStart = _process.stdin.close; | 332 _process._onStart = _process.stdin.close; |
| 336 | 333 |
| 337 // Setup process error handling. | 334 // Setup process error handling. |
| 338 _process.onError = (e) => _completer.completeException(e); | 335 _process._onError = (e) => _completer.completeException(e); |
| 339 | 336 |
| 340 // Setup process exit handling. | 337 // Setup process exit handling. |
| 341 _process.onExit = (exitCode) { | 338 _process.onExit = (exitCode) { |
| 342 _exitCode = exitCode; | 339 _exitCode = exitCode; |
| 343 _checkDone(); | 340 _checkDone(); |
| 344 }; | 341 }; |
| 345 | 342 |
| 346 // Setup stdout handling. | 343 // Setup stdout handling. |
| 347 _stdoutBuffer = new StringBuffer(); | 344 _stdoutBuffer = new StringBuffer(); |
| 348 var stdoutStream = new StringInputStream(_process.stdout, stdoutEncoding); | 345 var stdoutStream = new StringInputStream(_process.stdout, stdoutEncoding); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 390 | 387 |
| 391 class _ProcessResult implements ProcessResult { | 388 class _ProcessResult implements ProcessResult { |
| 392 const _ProcessResult(int this.exitCode, | 389 const _ProcessResult(int this.exitCode, |
| 393 String this.stdout, | 390 String this.stdout, |
| 394 String this.stderr); | 391 String this.stderr); |
| 395 | 392 |
| 396 final int exitCode; | 393 final int exitCode; |
| 397 final String stdout; | 394 final String stdout; |
| 398 final String stderr; | 395 final String stderr; |
| 399 } | 396 } |
| OLD | NEW |