| 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 class _ProcessStartStatus { | 5 class _ProcessStartStatus { |
| 6 int _errorCode; // Set to OS error code if process start failed. | 6 int _errorCode; // Set to OS error code if process start failed. |
| 7 String _errorMessage; // Set to OS error message if process start failed. | 7 String _errorMessage; // Set to OS error message if process start failed. |
| 8 } | 8 } |
| 9 | 9 |
| 10 | 10 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 } | 70 } |
| 71 _environment.add('$key=$value'); | 71 _environment.add('$key=$value'); |
| 72 }); | 72 }); |
| 73 } | 73 } |
| 74 | 74 |
| 75 _in = new _Socket._internalReadOnly(); // stdout coming from process. | 75 _in = new _Socket._internalReadOnly(); // stdout coming from process. |
| 76 _out = new _Socket._internalWriteOnly(); // stdin going to process. | 76 _out = new _Socket._internalWriteOnly(); // stdin going to process. |
| 77 _err = new _Socket._internalReadOnly(); // stderr coming from process. | 77 _err = new _Socket._internalReadOnly(); // stderr coming from process. |
| 78 _exitHandler = new _Socket._internalReadOnly(); | 78 _exitHandler = new _Socket._internalReadOnly(); |
| 79 _closed = false; | 79 _closed = false; |
| 80 _killed = false; | 80 _ended = false; |
| 81 _started = false; | 81 _started = false; |
| 82 _onExit = null; | 82 _onExit = null; |
| 83 // TODO(ager): Make the actual process starting really async instead of | 83 // TODO(ager): Make the actual process starting really async instead of |
| 84 // simulating it with a timer. | 84 // simulating it with a timer. |
| 85 new Timer(0, (Timer ignore) => _start()); | 85 new Timer(0, (Timer ignore) => _start()); |
| 86 } | 86 } |
| 87 | 87 |
| 88 String _windowsArgumentEscape(String argument) { | 88 String _windowsArgumentEscape(String argument) { |
| 89 var result = argument; | 89 var result = argument; |
| 90 if (argument.contains('\t') || argument.contains(' ')) { | 90 if (argument.contains('\t') || argument.contains(' ')) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 _exitHandler.inputStream.onData = () { | 171 _exitHandler.inputStream.onData = () { |
| 172 | 172 |
| 173 int exitCode(List<int> ints) { | 173 int exitCode(List<int> ints) { |
| 174 var code = _intFromBytes(ints, 0); | 174 var code = _intFromBytes(ints, 0); |
| 175 var negative = _intFromBytes(ints, 4); | 175 var negative = _intFromBytes(ints, 4); |
| 176 assert(negative == 0 || negative == 1); | 176 assert(negative == 0 || negative == 1); |
| 177 return (negative == 0) ? code : -code; | 177 return (negative == 0) ? code : -code; |
| 178 } | 178 } |
| 179 | 179 |
| 180 void handleExit() { | 180 void handleExit() { |
| 181 _ended = true; |
| 181 if (_onExit !== null) { | 182 if (_onExit !== null) { |
| 182 _onExit(exitCode(exitDataBuffer)); | 183 _onExit(exitCode(exitDataBuffer)); |
| 183 } | 184 } |
| 184 } | 185 } |
| 185 | 186 |
| 186 exitDataRead += _exitHandler.inputStream.readInto( | 187 exitDataRead += _exitHandler.inputStream.readInto( |
| 187 exitDataBuffer, exitDataRead, EXIT_DATA_SIZE - exitDataRead); | 188 exitDataBuffer, exitDataRead, EXIT_DATA_SIZE - exitDataRead); |
| 188 if (exitDataRead == EXIT_DATA_SIZE) handleExit(); | 189 if (exitDataRead == EXIT_DATA_SIZE) handleExit(); |
| 189 }; | 190 }; |
| 190 | 191 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 217 return _err.inputStream; | 218 return _err.inputStream; |
| 218 } | 219 } |
| 219 | 220 |
| 220 OutputStream get stdin() { | 221 OutputStream get stdin() { |
| 221 if (_closed) { | 222 if (_closed) { |
| 222 throw new ProcessException("Process closed"); | 223 throw new ProcessException("Process closed"); |
| 223 } | 224 } |
| 224 return _out.outputStream; | 225 return _out.outputStream; |
| 225 } | 226 } |
| 226 | 227 |
| 227 void kill() { | 228 void kill([ProcessSignal signal = ProcessSignal.SIGTERM]) { |
| 229 if (signal is! ProcessSignal) { |
| 230 throw new IllegalArgumentException( |
| 231 "Argument 'signal' must be a ProcessSignal"); |
| 232 } |
| 228 if (_closed && _pid === null) { | 233 if (_closed && _pid === null) { |
| 229 _reportError(new ProcessException("Process closed")); | 234 _reportError(new ProcessException("Process closed")); |
| 230 return; | 235 return; |
| 231 } | 236 } |
| 232 if (_killed) { | 237 if (_ended) { |
| 233 return; | 238 return; |
| 234 } | 239 } |
| 235 // TODO(ager): Make the actual kill operation asynchronous. | 240 // TODO(ager): Make the actual kill operation asynchronous. |
| 236 if (_kill(_pid)) { | 241 if (_kill(_pid, signal._signalNumber)) { |
| 237 _killed = true; | |
| 238 return; | 242 return; |
| 239 } | 243 } |
| 240 _reportError(new ProcessException("Could not kill process")); | 244 _reportError(new ProcessException("Could not kill process")); |
| 241 return; | 245 return; |
| 242 } | 246 } |
| 243 | 247 |
| 244 void _kill(int pid) native "Process_Kill"; | 248 void _kill(int pid, int signal) native "Process_Kill"; |
| 245 | 249 |
| 246 void close() { | 250 void close() { |
| 247 if (_closed) { | 251 if (_closed) { |
| 248 throw new ProcessException("Process closed"); | 252 throw new ProcessException("Process closed"); |
| 249 } | 253 } |
| 250 _in.close(); | 254 _in.close(); |
| 251 _out.close(); | 255 _out.close(); |
| 252 _err.close(); | 256 _err.close(); |
| 253 _exitHandler.close(); | 257 _exitHandler.close(); |
| 254 _closed = true; | 258 _closed = true; |
| 255 } | 259 } |
| 256 | 260 |
| 257 void set onExit(void callback(int exitCode)) { | 261 void set onExit(void callback(int exitCode)) { |
| 258 if (_closed) { | 262 if (_closed) { |
| 259 throw new ProcessException("Process closed"); | 263 throw new ProcessException("Process closed"); |
| 260 } | 264 } |
| 261 if (_killed) { | 265 if (_ended) { |
| 262 throw new ProcessException("Process killed"); | 266 throw new ProcessException("Process killed"); |
| 263 } | 267 } |
| 264 _onExit = callback; | 268 _onExit = callback; |
| 265 } | 269 } |
| 266 | 270 |
| 267 void set onError(void callback(e)) { | 271 void set onError(void callback(e)) { |
| 268 _onError = callback; | 272 _onError = callback; |
| 269 } | 273 } |
| 270 | 274 |
| 271 void set onStart(void callback()) { | 275 void set onStart(void callback()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 284 ObjectArray<String> _arguments; | 288 ObjectArray<String> _arguments; |
| 285 String _workingDirectory; | 289 String _workingDirectory; |
| 286 List<String> _environment; | 290 List<String> _environment; |
| 287 // Private methods of _Socket are used by _in, _out, and _err. | 291 // Private methods of _Socket are used by _in, _out, and _err. |
| 288 _Socket _in; | 292 _Socket _in; |
| 289 _Socket _out; | 293 _Socket _out; |
| 290 _Socket _err; | 294 _Socket _err; |
| 291 Socket _exitHandler; | 295 Socket _exitHandler; |
| 292 int _pid; | 296 int _pid; |
| 293 bool _closed; | 297 bool _closed; |
| 294 bool _killed; | 298 bool _ended; |
| 295 bool _started; | 299 bool _started; |
| 296 Function _onExit; | 300 Function _onExit; |
| 297 Function _onError; | 301 Function _onError; |
| 298 Function _onStart; | 302 Function _onStart; |
| 299 } | 303 } |
| 300 | 304 |
| 301 | 305 |
| 302 // _NonInteractiveProcess is a wrapper around an interactive process | 306 // _NonInteractiveProcess is a wrapper around an interactive process |
| 303 // that buffers output so it can be delivered when the process exits. | 307 // that buffers output so it can be delivered when the process exits. |
| 304 // _NonInteractiveProcess is used to implement the Process.run | 308 // _NonInteractiveProcess is used to implement the Process.run |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 | 394 |
| 391 class _ProcessResult implements ProcessResult { | 395 class _ProcessResult implements ProcessResult { |
| 392 const _ProcessResult(int this.exitCode, | 396 const _ProcessResult(int this.exitCode, |
| 393 String this.stdout, | 397 String this.stdout, |
| 394 String this.stderr); | 398 String this.stderr); |
| 395 | 399 |
| 396 final int exitCode; | 400 final int exitCode; |
| 397 final String stdout; | 401 final String stdout; |
| 398 final String stderr; | 402 final String stderr; |
| 399 } | 403 } |
| OLD | NEW |