awesome.spawn: Add exit status support
This adds a new argument to awesome.spawn. This argument is a function that will be called with the exit status once the spawned process terminates. For normal exit, the function is called with "exit" and the exit code. If the process is terminated by a signal, the function will be called with "signal" and the signal number of the signal that caused termination. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
58bd21ad79
commit
a8ac146bd0
42
spawn.c
42
spawn.c
|
@ -342,6 +342,28 @@ parse_command(lua_State *L, int idx, GError **error)
|
|||
return argv;
|
||||
}
|
||||
|
||||
/** Callback for when a spawned process exits. */
|
||||
static void
|
||||
child_exit_callback(GPid pid, gint status, gpointer user_data)
|
||||
{
|
||||
lua_State *L = globalconf_get_lua_State();
|
||||
int exit_callback = GPOINTER_TO_INT(user_data);
|
||||
|
||||
/* 'Decode' the exit status */
|
||||
if (WIFEXITED(status)) {
|
||||
lua_pushliteral(L, "exit");
|
||||
lua_pushnumber(L, WEXITSTATUS(status));
|
||||
} else {
|
||||
assert(WIFSIGNALED(status));
|
||||
lua_pushliteral(L, "signal");
|
||||
lua_pushnumber(L, WTERMSIG(status));
|
||||
}
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, exit_callback);
|
||||
luaA_dofunction(L, 2, 0);
|
||||
luaA_unregister(L, &exit_callback);
|
||||
}
|
||||
|
||||
/** Spawn a program.
|
||||
* The program will be started on the default screen.
|
||||
*
|
||||
|
@ -350,6 +372,9 @@ parse_command(lua_State *L, int idx, GError **error)
|
|||
* @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?
|
||||
* @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
|
||||
* code / the signal number causing process termination.
|
||||
* @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.
|
||||
|
@ -365,6 +390,7 @@ luaA_spawn(lua_State *L)
|
|||
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;
|
||||
GSpawnFlags flags = 0;
|
||||
gboolean retval;
|
||||
GPid pid;
|
||||
|
||||
|
@ -376,6 +402,11 @@ luaA_spawn(lua_State *L)
|
|||
return_stdout = luaA_checkboolean(L, 4);
|
||||
if(lua_gettop(L) >= 5)
|
||||
return_stderr = luaA_checkboolean(L, 5);
|
||||
if(lua_gettop(L) >= 6)
|
||||
{
|
||||
luaA_checkfunction(L, 6);
|
||||
flags |= G_SPAWN_DO_NOT_REAP_CHILD;
|
||||
}
|
||||
if(return_stdin)
|
||||
stdin_ptr = &stdin_fd;
|
||||
if(return_stdout)
|
||||
|
@ -409,7 +440,8 @@ luaA_spawn(lua_State *L)
|
|||
g_timeout_add_seconds(AWESOME_SPAWN_TIMEOUT, spawn_launchee_timeout, context);
|
||||
}
|
||||
|
||||
retval = g_spawn_async_with_pipes(NULL, argv, NULL, G_SPAWN_SEARCH_PATH,
|
||||
flags |= G_SPAWN_SEARCH_PATH;
|
||||
retval = g_spawn_async_with_pipes(NULL, argv, NULL, flags,
|
||||
spawn_callback, context, &pid,
|
||||
stdin_ptr, stdout_ptr, stderr_ptr, &error);
|
||||
g_strfreev(argv);
|
||||
|
@ -424,6 +456,14 @@ luaA_spawn(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if(flags & G_SPAWN_DO_NOT_REAP_CHILD)
|
||||
{
|
||||
int exit_callback = LUA_REFNIL;
|
||||
/* Only do this down here to avoid leaks in case of errors */
|
||||
luaA_registerfct(L, 6, &exit_callback);
|
||||
g_child_watch_add(pid, child_exit_callback, GINT_TO_POINTER(exit_callback));
|
||||
}
|
||||
|
||||
/* push pid on stack */
|
||||
lua_pushnumber(L, pid);
|
||||
|
||||
|
|
Loading…
Reference in New Issue