awesome.spawn: Add a new argument for env

This adds a new argument to awesome.spawn that can be used to specify
the environment of the spawned process.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2017-08-12 16:39:39 +02:00 committed by Daniel Hahler
parent aac519b946
commit 9f8ff76079
2 changed files with 39 additions and 3 deletions

18
spawn.c
View File

@ -475,6 +475,8 @@ child_exit_callback(GPid pid, gint status, gpointer user_data)
* @tparam[opt=nil] function exit_callback Function to call on process exit. The * @tparam[opt=nil] function exit_callback Function to call on process exit. The
* function arguments will be type of exit ("exit" or "signal") and the exit * function arguments will be type of exit ("exit" or "signal") and the exit
* code / the signal number causing process termination. * code / the signal number causing process termination.
* @tparam[opt=nil] table cmd The environment to use for the spawned program.
* Without this, the spawned process inherits awesome's environment.
* @treturn[1] integer Process ID if everything is OK. * @treturn[1] integer Process ID if everything is OK.
* @treturn[1] string Startup-notification ID, if `use_sn` is true. * @treturn[1] string Startup-notification ID, if `use_sn` is true.
* @treturn[1] integer stdin, if `stdin` is true. * @treturn[1] integer stdin, if `stdin` is true.
@ -486,7 +488,7 @@ child_exit_callback(GPid pid, gint status, gpointer user_data)
int int
luaA_spawn(lua_State *L) luaA_spawn(lua_State *L)
{ {
gchar **argv = NULL; gchar **argv = NULL, **envp = NULL;
bool use_sn = true, return_stdin = false, return_stdout = false, return_stderr = false; 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_fd = -1, stdout_fd = -1, stderr_fd = -1;
int *stdin_ptr = NULL, *stdout_ptr = NULL, *stderr_ptr = NULL; int *stdin_ptr = NULL, *stdout_ptr = NULL, *stderr_ptr = NULL;
@ -528,6 +530,17 @@ luaA_spawn(lua_State *L)
return 1; return 1;
} }
if (!lua_isnoneornil(L, 7)) {
envp = parse_table_array(L, 7, &error);
if (error) {
g_strfreev(argv);
g_strfreev(envp);
lua_pushfstring(L, "spawn: environment parse error: %s", error->message);
g_error_free(error);
return 1;
}
}
SnLauncherContext *context = NULL; SnLauncherContext *context = NULL;
if(use_sn) if(use_sn)
{ {
@ -543,10 +556,11 @@ luaA_spawn(lua_State *L)
} }
flags |= G_SPAWN_SEARCH_PATH | G_SPAWN_CLOEXEC_PIPES; flags |= G_SPAWN_SEARCH_PATH | G_SPAWN_CLOEXEC_PIPES;
retval = g_spawn_async_with_pipes(NULL, argv, NULL, flags, retval = g_spawn_async_with_pipes(NULL, argv, envp, flags,
spawn_callback, context, &pid, spawn_callback, context, &pid,
stdin_ptr, stdout_ptr, stderr_ptr, &error); stdin_ptr, stdout_ptr, stderr_ptr, &error);
g_strfreev(argv); g_strfreev(argv);
g_strfreev(envp);
if(!retval) if(!retval)
{ {
lua_pushstring(L, error->message); lua_pushstring(L, error->message);

View File

@ -71,6 +71,28 @@ local steps = {
end end
}) })
-- Test that setting env vars works and that the env is cleared
local read_line = false
local pid, _, _, stdout = awesome.spawn({ "sh", "-c", "echo $AWESOME_SPAWN_TEST_VAR $HOME $USER" },
false, false, true, false, nil, { "AWESOME_SPAWN_TEST_VAR=42" })
assert(type(pid) ~= "string", pid)
spawn.read_lines(require("lgi").Gio.UnixInputStream.new(stdout, true),
function(line)
assert(not read_line)
read_line = true
assert(line == "42", line)
spawns_done = spawns_done + 1
end, nil, true)
-- Test error in parse_table_array.
pid = awesome.spawn({"true"}, false, false, true, false, nil, { 0 })
assert(pid == 'spawn: environment parse error: Non-string argument at table index 1', pid)
-- Test error in parse_command.
pid = awesome.spawn({0}, false, false, true, false, nil, {})
assert(pid == 'spawn: parse error: Non-string argument at table index 1', pid)
local steps_count = 0 local steps_count = 0
local err_count = 0 local err_count = 0
spawn.with_line_callback({ "sh", "-c", "printf line1\\\\nline2\\\\nline3 ; echo err >&2 ; exit 42" }, { spawn.with_line_callback({ "sh", "-c", "printf line1\\\\nline2\\\\nline3 ; echo err >&2 ; exit 42" }, {
@ -98,7 +120,7 @@ local steps = {
end end
}) })
end end
if spawns_done == 2 then if spawns_done == 3 then
assert(exit_yay == 0) assert(exit_yay == 0)
assert(exit_snd == 42) assert(exit_snd == 42)
assert(async_spawns_done == 2) assert(async_spawns_done == 2)