From 6a8c41cd1d5e218d0dacffb836fdd7d4ec6333dd Mon Sep 17 00:00:00 2001 From: Aylur Date: Mon, 14 Oct 2024 16:01:36 +0000 Subject: feat: astal-io --- lib/astal/io/process.vala | 119 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 lib/astal/io/process.vala (limited to 'lib/astal/io/process.vala') diff --git a/lib/astal/io/process.vala b/lib/astal/io/process.vala new file mode 100644 index 0000000..e8637ab --- /dev/null +++ b/lib/astal/io/process.vala @@ -0,0 +1,119 @@ +public class AstalIO.Process : Object { + 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) + stdout(output.strip()); + else + stderr(output.strip()); + + read_stream(stream, err); + } + } catch (Error err) { + printerr("%s\n", err.message); + } + }); + } + + private DataInputStream out_stream; + private DataInputStream err_stream; + private DataOutputStream in_stream; + private Subprocess process; + public string[] argv { construct; get; } + + public signal void stdout (string out); + public signal void stderr (string err); + + public void kill() { + process.force_exit(); + } + + public void signal(int signal_num) { + process.send_signal(signal_num); + } + + public void write(string in) throws Error { + in_stream.put_string(in); + } + + public void write_async(string in) { + in_stream.write_all_async.begin( + in.data, + Priority.DEFAULT, null, (_, res) => { + try { + in_stream.write_all_async.end(res, null); + } catch (Error err) { + printerr("%s\n", err.message); + } + } + ); + } + + public Process.subprocessv(string[] cmd) throws Error { + Object(argv: 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); + } + + public static Process subprocess(string cmd) throws Error { + string[] argv; + Shell.parse_argv(cmd, out argv); + return new Process.subprocessv(argv); + } + + public static string execv(string[] cmd) throws Error { + var process = new Subprocess.newv( + cmd, + SubprocessFlags.STDERR_PIPE | + SubprocessFlags.STDOUT_PIPE + ); + + 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) + return out_str.strip(); + else + throw new IOError.FAILED(err_str.strip()); + } + + public static string exec(string cmd) throws Error { + string[] argv; + Shell.parse_argv(cmd, out argv); + return Process.execv(argv); + } + + public static async string exec_asyncv(string[] cmd) throws Error { + var process = new Subprocess.newv( + cmd, + SubprocessFlags.STDERR_PIPE | + SubprocessFlags.STDOUT_PIPE + ); + + 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) + return out_str.strip(); + else + throw new IOError.FAILED(err_str.strip()); + } + + public static async string exec_async(string cmd) throws Error { + string[] argv; + Shell.parse_argv(cmd, out argv); + return yield exec_asyncv(argv); + } +} -- cgit v1.2.3 From ecfbf082bfab22e34d8036896f51069ce0c18302 Mon Sep 17 00:00:00 2001 From: Aylur Date: Tue, 15 Oct 2024 20:58:49 +0000 Subject: docs: astal-io doc comments --- lib/astal/io/process.vala | 75 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 11 deletions(-) (limited to 'lib/astal/io/process.vala') diff --git a/lib/astal/io/process.vala b/lib/astal/io/process.vala index e8637ab..8767012 100644 --- a/lib/astal/io/process.vala +++ b/lib/astal/io/process.vala @@ -1,3 +1,6 @@ +/** + * `Process` provides shortcuts for [class@GLib.Subprocess] with sane defaults. + */ public class AstalIO.Process : Object { private void read_stream(DataInputStream stream, bool err) { stream.read_line_utf8_async.begin(Priority.DEFAULT, null, (_, res) => { @@ -23,34 +26,56 @@ public class AstalIO.Process : Object { private Subprocess process; public string[] argv { construct; get; } + + /** + * When the underlying subprocess writes to its stdout + * this signal is emitted with that line. + */ public signal void stdout (string out); + + /** + * When the underlying subprocess writes to its stderr + * this signal is emitted with that line. + */ public signal void stderr (string err); + /** + * Force quit the subprocess. + */ public void kill() { process.force_exit(); } + /** + * Send a signal to the subprocess. + */ public void signal(int signal_num) { process.send_signal(signal_num); } + /** + * Write a line to the subprocess' stdin synchronously. + */ public void write(string in) throws Error { in_stream.put_string(in); } - public void write_async(string in) { - in_stream.write_all_async.begin( - in.data, - Priority.DEFAULT, null, (_, res) => { - try { - in_stream.write_all_async.end(res, null); - } catch (Error err) { - printerr("%s\n", err.message); - } - } - ); + /** + * Write a line to the subprocess' stdin asynchronously. + */ + public async void write_async(string in) { + try { + yield in_stream.write_all_async(in.data, in.data.length, null, null); + } catch (Error err) { + printerr("%s\n", err.message); + } } + /** + * 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 { Object(argv: cmd); process = new Subprocess.newv(cmd, @@ -65,12 +90,22 @@ public class AstalIO.Process : Object { read_stream(err_stream, false); } + /** + * Start a new subprocess with the given command + * which is parsed using [func@Shell.parse_argv]. + */ public static Process subprocess(string cmd) throws Error { string[] argv; Shell.parse_argv(cmd, out argv); return new Process.subprocessv(argv); } + /** + * Execute a command synchronously. + * The first element of the vector is executed with the remaining elements as the argument list. + * + * @return stdout of the subprocess + */ public static string execv(string[] cmd) throws Error { var process = new Subprocess.newv( cmd, @@ -88,12 +123,24 @@ public class AstalIO.Process : Object { throw new IOError.FAILED(err_str.strip()); } + /** + * Execute a command synchronously. + * The command is parsed using [func@Shell.parse_argv]. + * + * @return stdout of the subprocess + */ public static string exec(string cmd) throws Error { string[] argv; Shell.parse_argv(cmd, out argv); return Process.execv(argv); } + /** + * Execute a command asynchronously. + * The first element of the vector is executed with the remaining elements as the argument list. + * + * @return stdout of the subprocess + */ public static async string exec_asyncv(string[] cmd) throws Error { var process = new Subprocess.newv( cmd, @@ -111,6 +158,12 @@ public class AstalIO.Process : Object { throw new IOError.FAILED(err_str.strip()); } + /** + * Execute a command asynchronously. + * The command is parsed using [func@Shell.parse_argv]. + * + * @return stdout of the subprocess + */ public static async string exec_async(string cmd) throws Error { string[] argv; Shell.parse_argv(cmd, out argv); -- cgit v1.2.3 From 306e64998c1bf1fb997c1098ae92d6edfef31cd2 Mon Sep 17 00:00:00 2001 From: Aylur Date: Wed, 23 Oct 2024 20:37:32 +0000 Subject: docs: astal3 and io comments --- lib/astal/io/process.vala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/astal/io/process.vala') diff --git a/lib/astal/io/process.vala b/lib/astal/io/process.vala index 8767012..cfd05b9 100644 --- a/lib/astal/io/process.vala +++ b/lib/astal/io/process.vala @@ -1,5 +1,5 @@ /** - * `Process` provides shortcuts for [class@GLib.Subprocess] with sane defaults. + * `Process` provides shortcuts for [class@Gio.Subprocess] with sane defaults. */ public class AstalIO.Process : Object { private void read_stream(DataInputStream stream, bool err) { @@ -92,7 +92,7 @@ public class AstalIO.Process : Object { /** * Start a new subprocess with the given command - * which is parsed using [func@Shell.parse_argv]. + * which is parsed using [func@GLib.shell_parse_argv]. */ public static Process subprocess(string cmd) throws Error { string[] argv; @@ -125,7 +125,7 @@ public class AstalIO.Process : Object { /** * Execute a command synchronously. - * The command is parsed using [func@Shell.parse_argv]. + * The command is parsed using [func@GLib.shell_parse_argv]. * * @return stdout of the subprocess */ @@ -160,7 +160,7 @@ public class AstalIO.Process : Object { /** * Execute a command asynchronously. - * The command is parsed using [func@Shell.parse_argv]. + * The command is parsed using [func@GLib.shell_parse_argv]. * * @return stdout of the subprocess */ -- cgit v1.2.3