OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 part of dart.io; | 5 part of dart.io; |
6 | 6 |
7 // TODO(ager): The only reason for this class is that we | 7 // TODO(ager): The only reason for this class is that we |
8 // cannot patch a top-level at this point. | 8 // cannot patch a top-level at this point. |
9 class _ProcessUtils { | 9 class _ProcessUtils { |
10 external static void _exit(int status); | 10 external static void _exit(int status); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 } | 93 } |
94 _ProcessUtils._sleep(milliseconds); | 94 _ProcessUtils._sleep(milliseconds); |
95 } | 95 } |
96 | 96 |
97 /** | 97 /** |
98 * Returns the PID of the current process. | 98 * Returns the PID of the current process. |
99 */ | 99 */ |
100 int get pid => _ProcessUtils._pid(null); | 100 int get pid => _ProcessUtils._pid(null); |
101 | 101 |
102 /** | 102 /** |
| 103 * Modes for running a new process. |
| 104 */ |
| 105 enum ProcessStartMode { |
| 106 /// Normal child process. |
| 107 NORMAL, |
| 108 /// Detached child process with no open communication channel. |
| 109 DETACHED, |
| 110 /// Detached child process with stdin, stdout and stderr still open |
| 111 /// for communication with the child. |
| 112 DETACHED_WITH_STDIO |
| 113 } |
| 114 |
| 115 /** |
103 * The means to execute a program. | 116 * The means to execute a program. |
104 * | 117 * |
105 * Use the static [start] and [run] methods to start a new process. | 118 * Use the static [start] and [run] methods to start a new process. |
106 * The run method executes the process non-interactively to completion. | 119 * The run method executes the process non-interactively to completion. |
107 * In contrast, the start method allows your code to interact with the | 120 * In contrast, the start method allows your code to interact with the |
108 * running process. | 121 * running process. |
109 * | 122 * |
110 * ## Start a process with the run method | 123 * ## Start a process with the run method |
111 * | 124 * |
112 * The following code sample uses the run method to create a process | 125 * The following code sample uses the run method to create a process |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 * include the parent process's environment, with [environment] taking | 254 * include the parent process's environment, with [environment] taking |
242 * precedence. Default is `true`. | 255 * precedence. Default is `true`. |
243 * | 256 * |
244 * If [runInShell] is `true`, the process will be spawned through a system | 257 * If [runInShell] is `true`, the process will be spawned through a system |
245 * shell. On Linux and Mac OS, [:/bin/sh:] is used, while | 258 * shell. On Linux and Mac OS, [:/bin/sh:] is used, while |
246 * [:%WINDIR%\system32\cmd.exe:] is used on Windows. | 259 * [:%WINDIR%\system32\cmd.exe:] is used on Windows. |
247 * | 260 * |
248 * Users must read all data coming on the [stdout] and [stderr] | 261 * Users must read all data coming on the [stdout] and [stderr] |
249 * streams of processes started with [:Process.start:]. If the user | 262 * streams of processes started with [:Process.start:]. If the user |
250 * does not read all data on the streams the underlying system | 263 * does not read all data on the streams the underlying system |
251 * resources will not be freed since there is still pending data. | 264 * resources will not be released since there is still pending data. |
252 * | 265 * |
253 * The following code uses `Process.start` to grep for `main` in the | 266 * The following code uses `Process.start` to grep for `main` in the |
254 * file `test.dart` on Linux. | 267 * file `test.dart` on Linux. |
255 * | 268 * |
256 * Process.start('grep', ['-i', 'main', 'test.dart']).then((process) { | 269 * Process.start('grep', ['-i', 'main', 'test.dart']).then((process) { |
257 * stdout.addStream(process.stdout); | 270 * stdout.addStream(process.stdout); |
258 * stderr.addStream(process.stderr); | 271 * stderr.addStream(process.stderr); |
259 * }); | 272 * }); |
260 * | 273 * |
261 * If [detach] is `true` a detached process will be created. A | 274 * If [mode] is [ProcessStartMode.NORMAL] (the default) a child |
262 * detached process has no connection to its parent, and can | 275 * process will be started with `stdin`, `stdout` and `stderr` |
263 * keep running on its own when the parent dies. The only | 276 * connected. |
| 277 * |
| 278 * If `mode` is [ProcessStartMode.DETACHED] a detached process will |
| 279 * be created. A detached process has no connection to its parent, |
| 280 * and can keep running on its own when the parent dies. The only |
264 * information available from a detached process is its `pid`. There | 281 * information available from a detached process is its `pid`. There |
265 * is no connection to its `stdin`, `stdout` or `stderr` nor will its | 282 * is no connection to its `stdin`, `stdout` or `stderr`, nor will |
266 * exit code become available when it terminates. | 283 * the process' exit code become available when it terminates. |
| 284 * |
| 285 * If `mode` is [ProcessStartMode.DETACHED_WITH_STDIO] a detached |
| 286 * process will be created where the `stdin`, `stdout` and `stderr` |
| 287 * are connected. The creator can communicate with the child through |
| 288 * these. The detached process will keep running even if these |
| 289 * communication channels are closed. The process' exit code will |
| 290 * not become available when it terminated. |
| 291 * |
| 292 * The default value for `mode` is `ProcessStartMode.NORMAL`. |
267 */ | 293 */ |
268 external static Future<Process> start( | 294 external static Future<Process> start( |
269 String executable, | 295 String executable, |
270 List<String> arguments, | 296 List<String> arguments, |
271 {String workingDirectory, | 297 {String workingDirectory, |
272 Map<String, String> environment, | 298 Map<String, String> environment, |
273 bool includeParentEnvironment: true, | 299 bool includeParentEnvironment: true, |
274 bool runInShell: false, | 300 bool runInShell: false, |
275 bool detach: false}); | 301 ProcessStartMode mode: ProcessStartMode.NORMAL}); |
276 | 302 |
277 /** | 303 /** |
278 * Starts a process and runs it non-interactively to completion. The | 304 * Starts a process and runs it non-interactively to completion. The |
279 * process run is [executable] with the specified [arguments]. | 305 * process run is [executable] with the specified [arguments]. |
280 * | 306 * |
281 * Use [workingDirectory] to set the working directory for the process. Note | 307 * Use [workingDirectory] to set the working directory for the process. Note |
282 * that the change of directory occurs before executing the process on some | 308 * that the change of directory occurs before executing the process on some |
283 * platforms, which may have impact when using relative paths for the | 309 * platforms, which may have impact when using relative paths for the |
284 * executable and the arguments. | 310 * executable and the arguments. |
285 * | 311 * |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 final int errorCode; | 547 final int errorCode; |
522 | 548 |
523 const ProcessException(this.executable, this.arguments, [this.message = "", | 549 const ProcessException(this.executable, this.arguments, [this.message = "", |
524 this.errorCode = 0]); | 550 this.errorCode = 0]); |
525 String toString() { | 551 String toString() { |
526 var msg = (message == null) ? 'OS error code: $errorCode' : message; | 552 var msg = (message == null) ? 'OS error code: $errorCode' : message; |
527 var args = arguments.join(' '); | 553 var args = arguments.join(' '); |
528 return "ProcessException: $msg\n Command: $executable $args"; | 554 return "ProcessException: $msg\n Command: $executable $args"; |
529 } | 555 } |
530 } | 556 } |
OLD | NEW |