| // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| part of dart.io; |
| |
| // TODO(ager): The only reason for this class is that we |
| // cannot patch a top-level at this point. |
| class _ProcessUtils { |
| external static Never _exit(int status); |
| external static void _setExitCode(int status); |
| external static int _getExitCode(); |
| external static void _sleep(int millis); |
| external static int _pid(Process? process); |
| external static Stream<ProcessSignal> _watchSignal(ProcessSignal signal); |
| } |
| |
| /// Exit the Dart VM process immediately with the given exit code. |
| /// |
| /// This does not wait for any asynchronous operations to terminate nor execute |
| /// `finally` blocks. Using [exit] is therefore very likely to lose data. |
| /// |
| /// While debugging, the VM will not respect the `--pause-isolates-on-exit` |
| /// flag if [exit] is called as invoking this method causes the Dart VM |
| /// process to shutdown immediately. To properly break on exit, consider |
| /// calling [debugger] from `dart:developer` or [Isolate.pause] from |
| /// `dart:isolate` on [Isolate.current] to pause the isolate before |
| /// invoking [exit]. |
| /// |
| /// The handling of exit codes is platform specific. |
| /// |
| /// On Linux and OS X an exit code for normal termination will always |
| /// be in the range [0..255]. If an exit code outside this range is |
| /// set the actual exit code will be the lower 8 bits masked off and |
| /// treated as an unsigned value. E.g. using an exit code of -1 will |
| /// result in an actual exit code of 255 being reported. |
| /// |
| /// On Windows the exit code can be set to any 32-bit value. However |
| /// some of these values are reserved for reporting system errors like |
| /// crashes. |
| /// |
| /// Besides this the Dart executable itself uses an exit code of `254` |
| /// for reporting compile time errors and an exit code of `255` for |
| /// reporting runtime error (unhandled exception). |
| /// |
| /// Due to these facts it is recommended to only use exit codes in the |
| /// range \[0..127\] for communicating the result of running a Dart |
| /// program to the surrounding environment. This will avoid any |
| /// cross-platform issues. |
| Never exit(int code) { |
| ArgumentError.checkNotNull(code, "code"); |
| if (!_EmbedderConfig._mayExit) { |
| throw new UnsupportedError( |
| "This embedder disallows calling dart:io's exit()"); |
| } |
| _ProcessUtils._exit(code); |
| } |
| |
| /// Set the global exit code for the Dart VM. |
| /// |
| /// The exit code is global for the Dart VM and the last assignment to |
| /// exitCode from any isolate determines the exit code of the Dart VM |
| /// on normal termination. |
| /// |
| /// Default value is `0`. |
| /// |
| /// See [exit] for more information on how to chose a value for the |
| /// exit code. |
| void set exitCode(int code) { |
| ArgumentError.checkNotNull(code, "code"); |
| _ProcessUtils._setExitCode(code); |
| } |
| |
| /// Get the global exit code for the Dart VM. |
| /// |
| /// The exit code is global for the Dart VM and the last assignment to |
| /// exitCode from any isolate determines the exit code of the Dart VM |
| /// on normal termination. |
| /// |
| /// See [exit] for more information on how to chose a value for the |
| /// exit code. |
| int get exitCode => _ProcessUtils._getExitCode(); |
| |
| /// Sleep for the duration specified in [duration]. |
| /// |
| /// Use this with care, as no asynchronous operations can be processed |
| /// in a isolate while it is blocked in a [sleep] call. |
| void sleep(Duration duration) { |
| int milliseconds = duration.inMilliseconds; |
| if (milliseconds < 0) { |
| throw new ArgumentError("sleep: duration cannot be negative"); |
| } |
| if (!_EmbedderConfig._maySleep) { |
| throw new UnsupportedError( |
| "This embedder disallows calling dart:io's sleep()"); |
| } |
| _ProcessUtils._sleep(milliseconds); |
| } |
| |
| /// Returns the PID of the current process. |
| int get pid => _ProcessUtils._pid(null); |
| |
| /// Methods for retrieving information about the current process. |
| class ProcessInfo { |
| /// The current resident set size of memory for the process. |
| /// |
| /// Note that the meaning of this field is platform dependent. For example, |
| /// some memory accounted for here may be shared with other processes, or if |
| /// the same page is mapped into a process's address space, it may be counted |
| /// twice. |
| external static int get currentRss; |
| |
| /// The high-watermark in bytes for the resident set size of memory for the |
| /// process. |
| /// |
| /// Note that the meaning of this field is platform dependent. For example, |
| /// some memory accounted for here may be shared with other processes, or if |
| /// the same page is mapped into a process's address space, it may be counted |
| /// twice. |
| external static int get maxRss; |
| } |
| |
| /// Modes for running a new process. |
| class ProcessStartMode { |
| /// Normal child process. |
| static const normal = const ProcessStartMode._internal(0); |
| @Deprecated("Use normal instead") |
| static const NORMAL = normal; |
| |
| /// Stdio handles are inherited by the child process. |
| static const inheritStdio = const ProcessStartMode._internal(1); |
| @Deprecated("Use inheritStdio instead") |
| static const INHERIT_STDIO = inheritStdio; |
| |
| /// Detached child process with no open communication channel. |
| static const detached = const ProcessStartMode._internal(2); |
| @Deprecated("Use detached instead") |
| static const DETACHED = detached; |
| |
| /// Detached child process with stdin, stdout and stderr still open |
| /// for communication with the child. |
| static const detachedWithStdio = const ProcessStartMode._internal(3); |
| @Deprecated("Use detachedWithStdio instead") |
| static const DETACHED_WITH_STDIO = detachedWithStdio; |
| |
| static List<ProcessStartMode> get values => const <ProcessStartMode>[ |
| normal, |
| inheritStdio, |
| detached, |
| detachedWithStdio |
| ]; |
| String toString() => |
| const ["normal", "inheritStdio", "detached", "detachedWithStdio"][_mode]; |
| |
| final int _mode; |
| const ProcessStartMode._internal(this._mode); |
| } |
| |
| /// The means to execute a program. |
| /// |
| /// Use the static [start] and [run] methods to start a new process. |
| /// The run method executes the process non-interactively to completion. |
| /// In contrast, the start method allows your code to interact with the |
| /// running process. |
| /// |
| /// ## Start a process with the run method |
| /// |
| /// The following code sample uses the run method to create a process |
| /// that runs the UNIX command `ls`, which lists the contents of a directory. |
| /// The run method completes with a [ProcessResult] object when the process |
| /// terminates. This provides access to the output and exit code from the |
| /// process. The run method does not return a `Process` object; |
| /// this prevents your code from interacting with the running process. |
| /// ```dart |
| /// import 'dart:io'; |
| /// |
| /// main() async { |
| /// // List all files in the current directory in UNIX-like systems. |
| /// var result = await Process.run('ls', ['-l']); |
| /// print(results.stdout); |
| /// } |
| /// ``` |
| /// ## Start a process with the start method |
| /// |
| /// The following example uses start to create the process. |
| /// The start method returns a [Future] for a `Process` object. |
| /// When the future completes the process is started and |
| /// your code can interact with the process: |
| /// writing to stdin, listening to stdout, and so on. |
| /// |
| /// The following sample starts the UNIX `cat` utility, which when given no |
| /// command-line arguments, echos its input. |
| /// The program writes to the process's standard input stream |
| /// and prints data from its standard output stream. |
| /// ```dart |
| /// import 'dart:io'; |
| /// import 'dart:convert'; |
| /// |
| /// main() async { |
| /// var process = await Process.start('cat', []); |
| /// process.stdout |
| /// .transform(utf8.decoder) |
| /// .forEach(print); |
| /// process.stdin.writeln('Hello, world!'); |
| /// process.stdin.writeln('Hello, galaxy!'); |
| /// process.stdin.writeln('Hello, universe!'); |
| /// } |
| /// ``` |
| /// ## Standard I/O streams |
| /// |
| /// As seen in the previous code sample, you can interact with the `Process`'s |
| /// standard output stream through the getter [stdout], |
| /// and you can interact with the `Process`'s standard input stream through |
| /// the getter [stdin]. |
| /// In addition, `Process` provides a getter [stderr] for using the `Process`'s |
| /// standard error stream. |
| /// |
| /// A `Process`'s streams are distinct from the top-level streams |
| /// for the current program. |
| /// |
| /// ## Exit codes |
| /// |
| /// Call the [exitCode] method to get the exit code of the process. |
| /// The exit code indicates whether the program terminated successfully |
| /// (usually indicated with an exit code of 0) or with an error. |
| /// |
| /// If the start method is used, the [exitCode] is available through a future |
| /// on the `Process` object (as shown in the example below). |
| /// If the run method is used, the [exitCode] is available |
| /// through a getter on the [ProcessResult] instance. |
| /// ```dart |
| /// import 'dart:io'; |
| /// |
| /// main() async { |
| /// var process = Process.start('ls', ['-l']); |
| /// var exitCode = await process.exitCode; |
| /// print('exit code: $exitCode'); |
| /// } |
| /// ``` |
| abstract class Process { |
| /// A `Future` which completes with the exit code of the process |
| /// when the process completes. |
| /// |
| /// The handling of exit codes is platform specific. |
| /// |
| /// On Linux and OS X a normal exit code will be a positive value in |
| /// the range [0..255]. If the process was terminated due to a signal |
| /// the exit code will be a negative value in the range [-255..-1], |
| /// where the absolute value of the exit code is the signal |
| /// number. For example, if a process crashes due to a segmentation |
| /// violation the exit code will be -11, as the signal SIGSEGV has the |
| /// number 11. |
| /// |
| /// On Windows a process can report any 32-bit value as an exit |
| /// code. When returning the exit code this exit code is turned into |
| /// a signed value. Some special values are used to report |
| /// termination due to some system event. E.g. if a process crashes |
| /// due to an access violation the 32-bit exit code is `0xc0000005`, |
| /// which will be returned as the negative number `-1073741819`. To |
| /// get the original 32-bit value use `(0x100000000 + exitCode) & |
| /// 0xffffffff`. |
| /// |
| /// There is no guarantee that [stdout] and [stderr] have finished reporting |
| /// the buffered output of the process when the returned future completes. |
| /// To be sure that all output is captured, |
| /// wait for the done event on the streams. |
| Future<int> get exitCode; |
| |
| /// Starts a process running the [executable] with the specified |
| /// [arguments]. |
| /// |
| /// Returns a `Future<Process>` that completes with a |
| /// [Process] instance when the process has been successfully |
| /// started. That [Process] object can be used to interact with the |
| /// process. If the process cannot be started the returned [Future] |
| /// completes with an exception. |
| /// |
| /// Use [workingDirectory] to set the working directory for the process. Note |
| /// that the change of directory occurs before executing the process on some |
| /// platforms, which may have impact when using relative paths for the |
| /// executable and the arguments. |
| /// |
| /// Use [environment] to set the environment variables for the process. If not |
| /// set the environment of the parent process is inherited. Currently, only |
| /// US-ASCII environment variables are supported and errors are likely to occur |
| /// if an environment variable with code-points outside the US-ASCII range is |
| /// passed in. |
| /// |
| /// If [includeParentEnvironment] is `true`, the process's environment will |
| /// include the parent process's environment, with [environment] taking |
| /// precedence. Default is `true`. |
| /// |
| /// If [runInShell] is `true`, the process will be spawned through a system |
| /// shell. On Linux and OS X, `/bin/sh` is used, while |
| /// `%WINDIR%\system32\cmd.exe` is used on Windows. |
| /// |
| /// Users must read all data coming on the [stdout] and [stderr] |
| /// streams of processes started with `Process.start`. If the user |
| /// does not read all data on the streams the underlying system |
| /// resources will not be released since there is still pending data. |
| /// |
| /// The following code uses `Process.start` to grep for `main` in the |
| /// file `test.dart` on Linux. |
| /// ```dart |
| /// var process = await Process.start('grep', ['-i', 'main', 'test.dart']); |
| /// stdout.addStream(process.stdout); |
| /// stderr.addStream(process.stderr); |
| /// ``` |
| /// If [mode] is [ProcessStartMode.normal] (the default) a child |
| /// process will be started with `stdin`, `stdout` and `stderr` |
| /// connected. |
| /// |
| /// If `mode` is [ProcessStartMode.detached] a detached process will |
| /// be created. A detached process has no connection to its parent, |
| /// and can keep running on its own when the parent dies. The only |
| /// information available from a detached process is its `pid`. There |
| /// is no connection to its `stdin`, `stdout` or `stderr`, nor will |
| /// the process' exit code become available when it terminates. |
| /// |
| /// If `mode` is [ProcessStartMode.detachedWithStdio] a detached |
| /// process will be created where the `stdin`, `stdout` and `stderr` |
| /// are connected. The creator can communicate with the child through |
| /// these. The detached process will keep running even if these |
| /// communication channels are closed. The process' exit code will |
| /// not become available when it terminated. |
| /// |
| /// The default value for `mode` is `ProcessStartMode.normal`. |
| external static Future<Process> start( |
| String executable, List<String> arguments, |
| {String? workingDirectory, |
| Map<String, String>? environment, |
| bool includeParentEnvironment = true, |
| bool runInShell = false, |
| ProcessStartMode mode = ProcessStartMode.normal}); |
| |
| /// Starts a process and runs it non-interactively to completion. The |
| /// process run is [executable] with the specified [arguments]. |
| /// |
| /// Use [workingDirectory] to set the working directory for the process. Note |
| /// that the change of directory occurs before executing the process on some |
| /// platforms, which may have impact when using relative paths for the |
| /// executable and the arguments. |
| /// |
| /// Use [environment] to set the environment variables for the process. If not |
| /// set the environment of the parent process is inherited. Currently, only |
| /// US-ASCII environment variables are supported and errors are likely to occur |
| /// if an environment variable with code-points outside the US-ASCII range is |
| /// passed in. |
| /// |
| /// If [includeParentEnvironment] is `true`, the process's environment will |
| /// include the parent process's environment, with [environment] taking |
| /// precedence. Default is `true`. |
| /// |
| /// If [runInShell] is true, the process will be spawned through a system |
| /// shell. On Linux and OS X, `/bin/sh` is used, while |
| /// `%WINDIR%\system32\cmd.exe` is used on Windows. |
| /// |
| /// The encoding used for decoding `stdout` and `stderr` into text is |
| /// controlled through [stdoutEncoding] and [stderrEncoding]. The |
| /// default encoding is [systemEncoding]. If `null` is used no |
| /// decoding will happen and the [ProcessResult] will hold binary |
| /// data. |
| /// |
| /// Returns a `Future<ProcessResult>` that completes with the |
| /// result of running the process, i.e., exit code, standard out and |
| /// standard in. |
| /// |
| /// The following code uses `Process.run` to grep for `main` in the |
| /// file `test.dart` on Linux. |
| /// ```dart |
| /// var result = await Process.run('grep', ['-i', 'main', 'test.dart']); |
| /// stdout.write(result.stdout); |
| /// stderr.write(result.stderr); |
| /// ``` |
| external static Future<ProcessResult> run( |
| String executable, List<String> arguments, |
| {String? workingDirectory, |
| Map<String, String>? environment, |
| bool includeParentEnvironment = true, |
| bool runInShell = false, |
| Encoding? stdoutEncoding = systemEncoding, |
| Encoding? stderrEncoding = systemEncoding}); |
| |
| /// Starts a process and runs it to completion. This is a synchronous |
| /// call and will block until the child process terminates. |
| /// |
| /// The arguments are the same as for [Process.run]. |
| /// |
| /// Returns a [ProcessResult] with the result of running the process, |
| /// i.e., exit code, standard out and standard in. |
| external static ProcessResult runSync( |
| String executable, List<String> arguments, |
| {String? workingDirectory, |
| Map<String, String>? environment, |
| bool includeParentEnvironment = true, |
| bool runInShell = false, |
| Encoding? stdoutEncoding = systemEncoding, |
| Encoding? stderrEncoding = systemEncoding}); |
| |
| /// Kills the process with id [pid]. |
| /// |
| /// Where possible, sends the [signal] to the process with id |
| /// [pid]. This includes Linux and OS X. The default signal is |
| /// [ProcessSignal.sigterm] which will normally terminate the |
| /// process. |
| /// |
| /// On platforms without signal support, including Windows, the call |
| /// just terminates the process with id [pid] in a platform specific |
| /// way, and the [signal] parameter is ignored. |
| /// |
| /// Returns `true` if the signal is successfully delivered to the |
| /// process. Otherwise the signal could not be sent, usually meaning |
| /// that the process is already dead. |
| external static bool killPid(int pid, |
| [ProcessSignal signal = ProcessSignal.sigterm]); |
| |
| /// The standard output stream of the process as a `Stream`. |
| Stream<List<int>> get stdout; |
| |
| /// The standard error stream of the process as a `Stream`. |
| Stream<List<int>> get stderr; |
| |
| /// The standard input stream of the process as an [IOSink]. |
| IOSink get stdin; |
| |
| /// The process id of the process. |
| int get pid; |
| |
| /// Kills the process. |
| /// |
| /// Where possible, sends the [signal] to the process. This includes |
| /// Linux and OS X. The default signal is [ProcessSignal.sigterm] |
| /// which will normally terminate the process. |
| /// |
| /// On platforms without signal support, including Windows, the call |
| /// just terminates the process in a platform specific way, and the |
| /// [signal] parameter is ignored. |
| /// |
| /// Returns `true` if the signal is successfully delivered to the |
| /// process. Otherwise the signal could not be sent, usually meaning |
| /// that the process is already dead. |
| bool kill([ProcessSignal signal = ProcessSignal.sigterm]); |
| } |
| |
| /// The result of running a non-interactive |
| /// process started with [Process.run] or [Process.runSync]. |
| class ProcessResult { |
| /// Exit code for the process. |
| /// |
| /// See [Process.exitCode] for more information in the exit code |
| /// value. |
| final int exitCode; |
| |
| /// Standard output from the process. The value used for the |
| /// `stdoutEncoding` argument to `Process.run` determines the type. If |
| /// `null` was used, this value is of type `List<int>` otherwise it is |
| /// of type `String`. |
| final stdout; |
| |
| /// Standard error from the process. The value used for the |
| /// `stderrEncoding` argument to `Process.run` determines the type. If |
| /// `null` was used, this value is of type `List<int>` |
| /// otherwise it is of type `String`. |
| final stderr; |
| |
| /// Process id of the process. |
| final int pid; |
| |
| ProcessResult(this.pid, this.exitCode, this.stdout, this.stderr); |
| } |
| |
| /// On Posix systems, [ProcessSignal] is used to send a specific signal |
| /// to a child process, see `Process.kill`. |
| /// |
| /// Some [ProcessSignal]s can also be watched, as a way to intercept the default |
| /// signal handler and implement another. See [ProcessSignal.watch] for more |
| /// information. |
| class ProcessSignal { |
| static const ProcessSignal sighup = const ProcessSignal._(1, "SIGHUP"); |
| static const ProcessSignal sigint = const ProcessSignal._(2, "SIGINT"); |
| static const ProcessSignal sigquit = const ProcessSignal._(3, "SIGQUIT"); |
| static const ProcessSignal sigill = const ProcessSignal._(4, "SIGILL"); |
| static const ProcessSignal sigtrap = const ProcessSignal._(5, "SIGTRAP"); |
| static const ProcessSignal sigabrt = const ProcessSignal._(6, "SIGABRT"); |
| static const ProcessSignal sigbus = const ProcessSignal._(7, "SIGBUS"); |
| static const ProcessSignal sigfpe = const ProcessSignal._(8, "SIGFPE"); |
| static const ProcessSignal sigkill = const ProcessSignal._(9, "SIGKILL"); |
| static const ProcessSignal sigusr1 = const ProcessSignal._(10, "SIGUSR1"); |
| static const ProcessSignal sigsegv = const ProcessSignal._(11, "SIGSEGV"); |
| static const ProcessSignal sigusr2 = const ProcessSignal._(12, "SIGUSR2"); |
| static const ProcessSignal sigpipe = const ProcessSignal._(13, "SIGPIPE"); |
| static const ProcessSignal sigalrm = const ProcessSignal._(14, "SIGALRM"); |
| static const ProcessSignal sigterm = const ProcessSignal._(15, "SIGTERM"); |
| static const ProcessSignal sigchld = const ProcessSignal._(17, "SIGCHLD"); |
| static const ProcessSignal sigcont = const ProcessSignal._(18, "SIGCONT"); |
| static const ProcessSignal sigstop = const ProcessSignal._(19, "SIGSTOP"); |
| static const ProcessSignal sigtstp = const ProcessSignal._(20, "SIGTSTP"); |
| static const ProcessSignal sigttin = const ProcessSignal._(21, "SIGTTIN"); |
| static const ProcessSignal sigttou = const ProcessSignal._(22, "SIGTTOU"); |
| static const ProcessSignal sigurg = const ProcessSignal._(23, "SIGURG"); |
| static const ProcessSignal sigxcpu = const ProcessSignal._(24, "SIGXCPU"); |
| static const ProcessSignal sigxfsz = const ProcessSignal._(25, "SIGXFSZ"); |
| static const ProcessSignal sigvtalrm = const ProcessSignal._(26, "SIGVTALRM"); |
| static const ProcessSignal sigprof = const ProcessSignal._(27, "SIGPROF"); |
| static const ProcessSignal sigwinch = const ProcessSignal._(28, "SIGWINCH"); |
| static const ProcessSignal sigpoll = const ProcessSignal._(29, "SIGPOLL"); |
| static const ProcessSignal sigsys = const ProcessSignal._(31, "SIGSYS"); |
| |
| @Deprecated("Use sighup instead") |
| static const ProcessSignal SIGHUP = sighup; |
| @Deprecated("Use sigint instead") |
| static const ProcessSignal SIGINT = sigint; |
| @Deprecated("Use sigquit instead") |
| static const ProcessSignal SIGQUIT = sigquit; |
| @Deprecated("Use sigill instead") |
| static const ProcessSignal SIGILL = sigill; |
| @Deprecated("Use sigtrap instead") |
| static const ProcessSignal SIGTRAP = sigtrap; |
| @Deprecated("Use sigabrt instead") |
| static const ProcessSignal SIGABRT = sigabrt; |
| @Deprecated("Use sigbus instead") |
| static const ProcessSignal SIGBUS = sigbus; |
| @Deprecated("Use sigfpe instead") |
| static const ProcessSignal SIGFPE = sigfpe; |
| @Deprecated("Use sigkill instead") |
| static const ProcessSignal SIGKILL = sigkill; |
| @Deprecated("Use sigusr1 instead") |
| static const ProcessSignal SIGUSR1 = sigusr1; |
| @Deprecated("Use sigsegv instead") |
| static const ProcessSignal SIGSEGV = sigsegv; |
| @Deprecated("Use sigusr2 instead") |
| static const ProcessSignal SIGUSR2 = sigusr2; |
| @Deprecated("Use sigpipe instead") |
| static const ProcessSignal SIGPIPE = sigpipe; |
| @Deprecated("Use sigalrm instead") |
| static const ProcessSignal SIGALRM = sigalrm; |
| @Deprecated("Use sigterm instead") |
| static const ProcessSignal SIGTERM = sigterm; |
| @Deprecated("Use sigchld instead") |
| static const ProcessSignal SIGCHLD = sigchld; |
| @Deprecated("Use sigcont instead") |
| static const ProcessSignal SIGCONT = sigcont; |
| @Deprecated("Use sigstop instead") |
| static const ProcessSignal SIGSTOP = sigstop; |
| @Deprecated("Use sigtstp instead") |
| static const ProcessSignal SIGTSTP = sigtstp; |
| @Deprecated("Use sigttin instead") |
| static const ProcessSignal SIGTTIN = sigttin; |
| @Deprecated("Use sigttou instead") |
| static const ProcessSignal SIGTTOU = sigttou; |
| @Deprecated("Use sigurg instead") |
| static const ProcessSignal SIGURG = sigurg; |
| @Deprecated("Use sigxcpu instead") |
| static const ProcessSignal SIGXCPU = sigxcpu; |
| @Deprecated("Use sigxfsz instead") |
| static const ProcessSignal SIGXFSZ = sigxfsz; |
| @Deprecated("Use sigvtalrm instead") |
| static const ProcessSignal SIGVTALRM = sigvtalrm; |
| @Deprecated("Use sigprof instead") |
| static const ProcessSignal SIGPROF = sigprof; |
| @Deprecated("Use sigwinch instead") |
| static const ProcessSignal SIGWINCH = sigwinch; |
| @Deprecated("Use sigpoll instead") |
| static const ProcessSignal SIGPOLL = sigpoll; |
| @Deprecated("Use sigsys instead") |
| static const ProcessSignal SIGSYS = sigsys; |
| |
| final int _signalNumber; |
| final String _name; |
| |
| const ProcessSignal._(this._signalNumber, this._name); |
| |
| String toString() => _name; |
| |
| /// Watch for process signals. |
| /// |
| /// The following [ProcessSignal]s can be listened to: |
| /// |
| /// * [ProcessSignal.sighup]. |
| /// * [ProcessSignal.sigint]. Signal sent by e.g. CTRL-C. |
| /// * [ProcessSignal.sigterm]. Not available on Windows. |
| /// * [ProcessSignal.sigusr1]. Not available on Windows. |
| /// * [ProcessSignal.sigusr2]. Not available on Windows. |
| /// * [ProcessSignal.sigwinch]. Not available on Windows. |
| /// |
| /// Other signals are disallowed, as they may be used by the VM. |
| /// |
| /// A signal can be watched multiple times, from multiple isolates, where all |
| /// callbacks are invoked when signaled, in no specific order. |
| Stream<ProcessSignal> watch() => _ProcessUtils._watchSignal(this); |
| } |
| |
| class SignalException implements IOException { |
| final String message; |
| final osError; |
| |
| const SignalException(this.message, [this.osError]); |
| |
| String toString() { |
| var msg = ""; |
| if (osError != null) { |
| msg = ", osError: $osError"; |
| } |
| return "SignalException: $message$msg"; |
| } |
| } |
| |
| class ProcessException implements IOException { |
| /// The executable provided for the process. |
| final String executable; |
| |
| /// The arguments provided for the process. |
| final List<String> arguments; |
| |
| /// The system message for the process exception, if any. |
| /// |
| /// The empty string if no message was available. |
| final String message; |
| |
| /// The OS error code for the process exception, if any. |
| /// |
| /// The value is zero if no OS error code was available. |
| final int errorCode; |
| |
| const ProcessException(this.executable, this.arguments, |
| [this.message = "", this.errorCode = 0]); |
| String toString() { |
| var args = arguments.join(' '); |
| return "ProcessException: $message\n Command: $executable $args"; |
| } |
| } |