Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(763)

Side by Side Diff: runtime/bin/process_patch.dart

Issue 13929002: Also wrap stdin/stdout/stderr on Process. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/bin/stdio_patch.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | runtime/bin/stdio_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698