[lua] Add a hook on standard fd activity

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-05-27 15:56:14 +02:00
parent 664dfcd0b8
commit 785c41f089
5 changed files with 101 additions and 10 deletions

View File

@ -279,12 +279,15 @@ main(int argc, char **argv)
char buf[1024];
const char *confpath = NULL;
int r, xfd, csfd, dbusfd, i, screen_nbr, opt;
ssize_t cmdlen = 1;
ssize_t len = 1;
const xcb_query_extension_reply_t *shape_query, *randr_query;
fd_set rd;
xcb_generic_event_t *ev;
struct sockaddr_un *addr;
client_t *c;
int pstdout[2], pstderr[2],
rstderr = -1, rstdout = -1,
a_stderr, a_stdout;
static struct option long_options[] =
{
{"help", 0, NULL, 'h'},
@ -298,15 +301,15 @@ main(int argc, char **argv)
/* save argv */
for(i = 0; i < argc; i++)
cmdlen += a_strlen(argv[i]) + 1;
len += a_strlen(argv[i]) + 1;
globalconf.argv = p_new(char, cmdlen);
a_strcpy(globalconf.argv, cmdlen, argv[0]);
globalconf.argv = p_new(char, len);
a_strcpy(globalconf.argv, len, argv[0]);
for(i = 1; i < argc; i++)
{
a_strcat(globalconf.argv, cmdlen, " ");
a_strcat(globalconf.argv, cmdlen, argv[i]);
a_strcat(globalconf.argv, len, " ");
a_strcat(globalconf.argv, len, argv[i]);
}
/* check args */
@ -376,6 +379,33 @@ main(int argc, char **argv)
atom_cache_list_init(&globalconf.atoms);
ewmh_init_atoms();
/* grab stdout and stderr */
if(pipe(pstdout) == -1)
{
perror("unable to pipe");
a_stdout = -1;
}
else
{
rstdout = dup(fileno(stdout));
dup2(pstdout[1], fileno(stdout));
a_stdout = pstdout[0];
/* stop making stdout buffered */
setvbuf(stdout, NULL, _IONBF, 0);
}
if(pipe(pstderr) == -1)
{
perror("unable to pipe");
a_stderr = -1;
}
else
{
rstderr = dup(fileno(stderr));
dup2(pstderr[1], fileno(stderr));
a_stderr = pstderr[0];
}
/* init screens struct */
globalconf.screens_info = screensinfo_new(globalconf.connection);
globalconf.screens = p_new(screen_t, globalconf.screens_info->nscreen);
@ -486,15 +516,41 @@ main(int argc, char **argv)
FD_SET(csfd, &rd);
if(dbusfd >= 0)
FD_SET(dbusfd, &rd);
if(a_stdout >= 0)
FD_SET(a_stdout, &rd);
if(a_stderr >= 0)
FD_SET(a_stderr, &rd);
FD_SET(xfd, &rd);
if(select(MAX(MAX(xfd, csfd), dbusfd) + 1, &rd, NULL, NULL, NULL) == -1)
if(select(MAX(MAX(MAX(MAX(xfd, csfd), dbusfd), a_stdout), a_stderr) + 1,
&rd, NULL, NULL, NULL) == -1)
{
if(errno == EINTR)
continue;
eprint("select failed");
}
/* Read and write stdout */
if(a_stdout >= 0 && FD_ISSET(a_stdout, &rd))
{
len = read(a_stdout, buf, sizeof(buf));
write(rstdout, buf, len);
/* call hook */
lua_pushlstring(globalconf.L, buf, len);
luaA_dofunction(globalconf.L, globalconf.hooks.fdactivity, 1);
}
if(a_stderr >= 0 && FD_ISSET(a_stderr, &rd))
{
len = read(a_stderr, buf, sizeof(buf));
write(rstderr, buf, len);
/* call hook */
lua_pushlstring(globalconf.L, buf, len);
luaA_dofunction(globalconf.L, globalconf.hooks.fdactivity, 1);
}
if(csfd >= 0 && FD_ISSET(csfd, &rd))
switch(r = recv(csfd, buf, sizeof(buf)-1, MSG_TRUNC))
switch(r = recv(csfd, buf, sizeof(buf) - 1, MSG_TRUNC))
{
case -1:
warn("error reading UNIX domain socket: %s", strerror(errno));

View File

@ -87,6 +87,16 @@ for s = 1, awesome.screen_count() do
mystatusbar:widget_add(mylayoutbox[s])
mystatusbar:add(s)
end
-- Create a textbox widget for debug messages on screen 1
mydebugbox = widget.new({ type = "textbox", name = "mydebugbox", align = "left" })
mydebugbox:set("text", "No debug information.")
mydebugbar = statusbar.new({ position = "off", name = "mydebugbar",
fg = "white", bg = "black" })
mydebugbar:widget_add(mydebugbox)
mydebugbar:add(1)
awesome.key({ modkey }, "d", function () mydebugbar:position_set("bottom") end)
awesome.key({ modkey, "Control" }, "d", function () mydebugbar:position_set("off") end)
-- }}}
-- {{{ Mouse bindings
@ -208,12 +218,20 @@ function hook_arrange(screen)
mylayoutbox[screen]:set("image", "@iconsdir@/layouts/" .. layout .. "w.png")
end
-- Hook function to print errors message
-- WARNING: you should _NOT_ print anything in this function
-- or you go into infinite loop
function hook_fdactivity(text)
mydebugbox:set("text", "<span font_desc=\"fixed 10\">" .. text .. "</span>")
end
-- Set up some hooks
hooks.focus(hook_focus)
hooks.unfocus(hook_unfocus)
hooks.newclient(hook_newclient)
hooks.mouseover(hook_mouseover)
hooks.arrange(hook_arrange)
hooks.fdactivity(hook_fdactivity)
-- }}}
-- Respect size hints

15
lua.c
View File

@ -359,6 +359,20 @@ luaA_hooks_titleupdate(lua_State *L)
return 0;
}
/** Set the function called on standard file descriptor (stdout and stderr) activity.
* This function is called with the output buffer text as argument.
* \param A function to call on each standard file descriptor activity.
*/
static int
luaA_hooks_fdactivity(lua_State *L)
{
luaA_checkfunction(L, 1);
if(globalconf.hooks.fdactivity)
luaL_unref(L, LUA_REGISTRYINDEX, globalconf.hooks.fdactivity);
globalconf.hooks.fdactivity = luaL_ref(L, LUA_REGISTRYINDEX);
return 0;
}
/** Set default font.
* \param A string with a font name in Pango format.
*/
@ -434,6 +448,7 @@ luaA_parserc(const char *rcfile)
{ "mouseover", luaA_hooks_mouseover },
{ "arrange", luaA_hooks_arrange },
{ "titleupdate", luaA_hooks_titleupdate },
{ "fdactivity", luaA_hooks_fdactivity },
{ NULL, NULL }
};

View File

@ -43,8 +43,6 @@ statusbar_draw(statusbar_t *statusbar)
int left = 0, right = 0;
area_t rectangle = { 0, 0, 0, 0, NULL, NULL };
statusbar->need_update.value = false;
if(!statusbar->position)
return;
@ -99,6 +97,8 @@ statusbar_refresh(void *p)
pthread_cond_wait(&statusbar->need_update.cond, &statusbar->need_update.lock);
statusbar_draw(statusbar);
statusbar->need_update.value = false;
pthread_mutex_unlock(&statusbar->need_update.lock);
}

View File

@ -429,6 +429,8 @@ struct awesome_t
luaA_function arrange;
/** Command to run on title change */
luaA_function titleupdate;
/** Command to run on every standard output printing */
luaA_function fdactivity;
} hooks;
};