Last active
August 29, 2015 14:26
-
-
Save psychon/8447f229fd313b5f3e3e to your computer and use it in GitHub Desktop.
Add function for reading other processes output, line by line or in total when the process is done
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/awesomerc.lua b/awesomerc.lua | |
index d9c7d07..a24b35c 100755 | |
--- a/awesomerc.lua | |
+++ b/awesomerc.lua | |
@@ -462,3 +462,46 @@ end) | |
client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) | |
client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) | |
-- }}} | |
+ | |
+local function spawn_with_lines_implementation(stream, line_callback, done_callback) | |
+ while true do | |
+ local line, length = stream:async_read_line() | |
+ if type(length) ~= "number" then | |
+ break -- error (and "line" is the error message) | |
+ end | |
+ if #line ~= length then | |
+ break -- end of file | |
+ end | |
+ line_callback(line) | |
+ end | |
+ stream:async_close() | |
+ if done_callback then | |
+ done_callback() | |
+ end | |
+end | |
+function spawn_with_lines(cmd, line_callback, done_callback) | |
+ local Gio = require("lgi").Gio | |
+ local pid, _, _, stdout, _ = awesome.spawn(cmd, false, false, true, false) | |
+ if type(pid) == "string" then | |
+ print("error: " .. pid) | |
+ return pid -- error | |
+ end | |
+ local stream = Gio.DataInputStream.new(Gio.UnixInputStream.new(stdout, true)) | |
+ Gio.Async.start(spawn_with_lines_implementation)(stream, line_callback, done_callback) | |
+end | |
+local spawn_with_output = function(cmd, callback) | |
+ local result = "" | |
+ spawn_with_lines(cmd, function(line) | |
+ result = result .. tostring(line) .. "\n" | |
+ end, function() | |
+ callback(result) | |
+ end) | |
+end | |
+ | |
+local cmd = { "bash", "-c", "for x in $(seq 1 3) ; do sleep 1 ; echo This is line number $x ; done" } | |
+spawn_with_lines(cmd, function(...) | |
+ print("Read a line:", ...) | |
+end) | |
+spawn_with_output(cmd, function(...) | |
+ print("Got output:", ...) | |
+end) | |
diff --git a/spawn.c b/spawn.c | |
index 8153ed3..2bba63e 100644 | |
--- a/spawn.c | |
+++ b/spawn.c | |
@@ -340,8 +340,14 @@ parse_command(lua_State *L, int idx, GError **error) | |
* | |
* @tparam string|table cmd The command to launch. | |
* @tparam[opt=true] boolean use_sn Use startup-notification? | |
+ * @tparam[opt=false] boolean stdin Return a fd for stdin? | |
+ * @tparam[opt=false] boolean stdout Return a fd for stdout? | |
+ * @tparam[opt=false] boolean stderr Return a fd for stderr? | |
* @treturn[1] integer Process ID if everything is OK. | |
* @treturn[1] string Startup-notification ID, if `use_sn` is true. | |
+ * @treturn[1] integer stdin, if `stdin` is true. | |
+ * @treturn[1] integer stdout, if `stdout` is true. | |
+ * @treturn[1] integer stderr, if `stderr` is true. | |
* @treturn[2] string An error string if an error occured. | |
* @function spawn | |
*/ | |
@@ -349,12 +355,26 @@ int | |
luaA_spawn(lua_State *L) | |
{ | |
gchar **argv = NULL; | |
- bool use_sn = true; | |
+ bool use_sn = true, return_stdin = false, return_stdout = false, return_stderr = false; | |
+ int stdin_fd = -1, stdout_fd = -1, stderr_fd = -1; | |
+ int *stdin_ptr = NULL, *stdout_ptr = NULL, *stderr_ptr = NULL; | |
gboolean retval; | |
GPid pid; | |
if(lua_gettop(L) >= 2) | |
use_sn = luaA_checkboolean(L, 2); | |
+ if(lua_gettop(L) >= 3) | |
+ return_stdin = luaA_checkboolean(L, 3); | |
+ if(lua_gettop(L) >= 4) | |
+ return_stdout = luaA_checkboolean(L, 4); | |
+ if(lua_gettop(L) >= 5) | |
+ return_stderr = luaA_checkboolean(L, 5); | |
+ if(return_stdin) | |
+ stdin_ptr = &stdin_fd; | |
+ if(return_stdout) | |
+ stdout_ptr = &stdout_fd; | |
+ if(return_stderr) | |
+ stderr_ptr = &stderr_fd; | |
GError *error = NULL; | |
argv = parse_command(L, 1, &error); | |
@@ -383,8 +403,9 @@ luaA_spawn(lua_State *L) | |
sn_launcher_context_setup_child_process(context); | |
} | |
- retval = g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, | |
- spawn_callback, NULL, &pid, &error); | |
+ retval = g_spawn_async_with_pipes(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, | |
+ spawn_callback, NULL, &pid, | |
+ stdin_ptr, stdout_ptr, stderr_ptr, &error); | |
g_strfreev(argv); | |
if(!retval) | |
{ | |
@@ -402,9 +423,24 @@ luaA_spawn(lua_State *L) | |
/* push sn on stack */ | |
if (context) | |
- lua_pushstring(L,sn_launcher_context_get_startup_id(context)); | |
+ lua_pushstring(L, sn_launcher_context_get_startup_id(context)); | |
+ else | |
+ lua_pushnil(L); | |
+ | |
+ if(return_stdin) | |
+ lua_pushinteger(L, stdin_fd); | |
+ else | |
+ lua_pushnil(L); | |
+ if(return_stdout) | |
+ lua_pushinteger(L, stdout_fd); | |
+ else | |
+ lua_pushnil(L); | |
+ if(return_stderr) | |
+ lua_pushinteger(L, stderr_fd); | |
+ else | |
+ lua_pushnil(L); | |
- return (context)?2:1; | |
+ return 5; | |
} | |
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment