| 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 |