diff options
Diffstat (limited to 'lib/astal/io/process.vala')
-rw-r--r-- | lib/astal/io/process.vala | 89 |
1 files changed, 64 insertions, 25 deletions
diff --git a/lib/astal/io/process.vala b/lib/astal/io/process.vala index cfd05b9..95c67a3 100644 --- a/lib/astal/io/process.vala +++ b/lib/astal/io/process.vala @@ -2,20 +2,22 @@ * `Process` provides shortcuts for [[email protected]] with sane defaults. */ public class AstalIO.Process : Object { + public string[] argv { construct; get; } + private void read_stream(DataInputStream stream, bool err) { stream.read_line_utf8_async.begin(Priority.DEFAULT, null, (_, res) => { try { var output = stream.read_line_utf8_async.end(res); if (output != null) { - if (err) + if (err) { stdout(output.strip()); - else + } else { stderr(output.strip()); - + } read_stream(stream, err); } } catch (Error err) { - printerr("%s\n", err.message); + critical(err.message); } }); } @@ -24,20 +26,27 @@ public class AstalIO.Process : Object { private DataInputStream err_stream; private DataOutputStream in_stream; private Subprocess process; - public string[] argv { construct; get; } + /** + * When the underlying subprocess writes to its stdout. + * + * @param out Line written to stdout + */ + public signal void stdout(string out); /** - * When the underlying subprocess writes to its stdout - * this signal is emitted with that line. + * When the underlying subprocess writes to its stderr. + * + * @param err Line written to stderr */ - public signal void stdout (string out); + public signal void stderr(string err); /** - * When the underlying subprocess writes to its stderr - * this signal is emitted with that line. + * When the underlying subprocess exits or is terminated. + * + * @param code Exit code or signal number if terminated */ - public signal void stderr (string err); + public signal void exit(int code, bool terminated); /** * Force quit the subprocess. @@ -48,6 +57,8 @@ public class AstalIO.Process : Object { /** * Send a signal to the subprocess. + * + * @param signal_num Signal number to be sent */ public void signal(int signal_num) { process.send_signal(signal_num); @@ -55,6 +66,8 @@ public class AstalIO.Process : Object { /** * Write a line to the subprocess' stdin synchronously. + * + * @param in String to be written to stdin */ public void write(string in) throws Error { in_stream.put_string(in); @@ -62,6 +75,8 @@ public class AstalIO.Process : Object { /** * Write a line to the subprocess' stdin asynchronously. + * + * @param in String to be written to stdin */ public async void write_async(string in) { try { @@ -71,23 +86,47 @@ public class AstalIO.Process : Object { } } - /** - * Start a new subprocess with the given command. - * - * The first element of the vector is executed with the remaining elements as the argument list. - */ - public Process.subprocessv(string[] cmd) throws Error { + /** See [[email protected]] */ + public Process(string[] cmd) throws Error { Object(argv: cmd); - process = new Subprocess.newv(cmd, + process = new Subprocess.newv( + cmd, SubprocessFlags.STDIN_PIPE | SubprocessFlags.STDERR_PIPE | SubprocessFlags.STDOUT_PIPE ); + out_stream = new DataInputStream(process.get_stdout_pipe()); err_stream = new DataInputStream(process.get_stderr_pipe()); in_stream = new DataOutputStream(process.get_stdin_pipe()); + read_stream(out_stream, true); read_stream(err_stream, false); + + process.wait_async.begin(null, (_, res) => { + try { + process.wait_async.end(res); + } catch (Error err) { + // ignore + } + + if (process.get_if_exited()) { + exit(process.get_exit_status(), false); + } + + if (process.get_if_signaled()) { + exit(process.get_term_sig(), true); + } + }); + } + + /** + * Start a new subprocess with the given command. + * + * The first element of the vector is executed with the remaining elements as the argument list. + */ + public static Process subprocessv(string[] cmd) throws Error { + return new Process(cmd); } /** @@ -97,7 +136,7 @@ public class AstalIO.Process : Object { public static Process subprocess(string cmd) throws Error { string[] argv; Shell.parse_argv(cmd, out argv); - return new Process.subprocessv(argv); + return Process.subprocessv(argv); } /** @@ -116,11 +155,11 @@ public class AstalIO.Process : Object { string err_str, out_str; process.communicate_utf8(null, null, out out_str, out err_str); var success = process.get_successful(); - process.dispose(); - if (success) + if (success) { return out_str.strip(); - else + } else { throw new IOError.FAILED(err_str.strip()); + } } /** @@ -151,11 +190,11 @@ public class AstalIO.Process : Object { string err_str, out_str; yield process.communicate_utf8_async(null, null, out out_str, out err_str); var success = process.get_successful(); - process.dispose(); - if (success) + if (success) { return out_str.strip(); - else + } else { throw new IOError.FAILED(err_str.strip()); + } } /** |