diff --git a/awesome.c b/awesome.c index ce987c5f5..c571db788 100644 --- a/awesome.c +++ b/awesome.c @@ -29,9 +29,7 @@ #include #include #include -#include #include -#include #include #include @@ -260,14 +258,12 @@ exit_help(int exit_code) int main(int argc, char **argv) { - char buf[1024]; const char *confpath = NULL; - int r, xfd, csfd, i, screen_nbr, opt; + int xfd, i, screen_nbr, opt; ssize_t cmdlen = 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; struct timeval select_timeout, hook_lastrun = { 0, 0 }, now, hook_nextrun; static struct option long_options[] = @@ -458,23 +454,7 @@ main(int argc, char **argv) xcb_aux_sync(globalconf.connection); - /* get socket fd */ - csfd = socket_getclient(); - addr = socket_getaddr(getenv("DISPLAY")); - - if(bind(csfd, (const struct sockaddr *) addr, SUN_LEN(addr))) - { - if(errno == EADDRINUSE) - { - if(unlink(addr->sun_path)) - warn("error unlinking existing file: %s", strerror(errno)); - if(bind(csfd, (const struct sockaddr *) addr, SUN_LEN(addr))) - warn("error binding UNIX domain socket: %s", strerror(errno)); - } - else - warn("error binding UNIX domain socket: %s", strerror(errno)); - } - + luaA_cs_init(); a_dbus_init(); /* register function for signals */ @@ -490,8 +470,6 @@ main(int argc, char **argv) while(running) { FD_ZERO(&rd); - if(csfd >= 0) - FD_SET(csfd, &rd); FD_SET(xfd, &rd); if(timerisset(&globalconf.timer)) { @@ -507,7 +485,7 @@ main(int argc, char **argv) else timersub(&hook_nextrun, &now, &select_timeout); } - if(select(MAX(xfd, csfd) + 1, &rd, + if(select(xfd + 1, &rd, NULL, NULL, timerisset(&globalconf.timer) ? &select_timeout : NULL) == -1) { @@ -515,21 +493,6 @@ main(int argc, char **argv) continue; eprint("select failed"); } - if(csfd >= 0 && FD_ISSET(csfd, &rd)) - switch(r = recv(csfd, buf, sizeof(buf)-1, MSG_TRUNC)) - { - case -1: - warn("error reading UNIX domain socket: %s", strerror(errno)); - csfd = -1; - break; - case 0: - break; - default: - if(r >= ssizeof(buf)) - break; - buf[r] = '\0'; - luaA_docmd(buf); - } /* Two level polling: * We need to first check we have an event to handle @@ -560,12 +523,7 @@ main(int argc, char **argv) } a_dbus_cleanup(); - - if(csfd > 0 && close(csfd)) - warn("error closing UNIX domain socket: %s", strerror(errno)); - if(unlink(addr->sun_path)) - warn("error unlinking UNIX domain socket: %s", strerror(errno)); - p_delete(&addr); + luaA_cs_cleanup(); /* remap all clients since some WM won't handle them otherwise */ for(c = globalconf.clients; c; c = c->next) diff --git a/lua.c b/lua.c index c040d2a27..1b4eb168f 100644 --- a/lua.c +++ b/lua.c @@ -19,9 +19,13 @@ * */ +#include #include +#include +#include #include +#include #include #include #include @@ -30,6 +34,7 @@ #include #include "config.h" +#include "common/socket.h" #include "structs.h" #include "lua.h" #include "tag.h" @@ -60,6 +65,9 @@ extern const struct luaL_reg awesome_statusbar_meta[]; extern const struct luaL_reg awesome_keybinding_methods[]; extern const struct luaL_reg awesome_keybinding_meta[]; +static struct sockaddr_un *addr; +static ev_io csio = { .fd = -1 }; + /** Add a global mouse binding. This binding will be available when you'll * click on root window. * \param L The Lua VM state. @@ -565,7 +573,7 @@ luaA_parserc(const char* rcfile) * \param cmd The buffer to parse. * \return true on succes, false on failure. */ -void +static void luaA_docmd(char *cmd) { char *p, *curcmd = cmd; @@ -578,3 +586,66 @@ luaA_docmd(char *cmd) curcmd = p + 1; } } + +static void +luaA_cb(EV_P_ ev_io *w, int revents) +{ + char buf[1024]; + int r; + + switch(r = recv(w->fd, buf, sizeof(buf)-1, MSG_TRUNC)) + { + case -1: + warn("error reading UNIX domain socket: %s", strerror(errno)); + luaA_cs_cleanup(); + break; + case 0: + break; + default: + if(r >= ssizeof(buf)) + break; + buf[r] = '\0'; + luaA_docmd(buf); + } +} + +void +luaA_cs_init(void) +{ + int csfd = socket_getclient(); + + if (csfd < 0) + return; + addr = socket_getaddr(getenv("DISPLAY")); + + if(bind(csfd, (const struct sockaddr *) addr, SUN_LEN(addr))) + { + if(errno == EADDRINUSE) + { + if(unlink(addr->sun_path)) + warn("error unlinking existing file: %s", strerror(errno)); + if(bind(csfd, (const struct sockaddr *) addr, SUN_LEN(addr))) + warn("error binding UNIX domain socket: %s", strerror(errno)); + } + else + warn("error binding UNIX domain socket: %s", strerror(errno)); + } + ev_io_init(&csio, &luaA_cb, csfd, EV_READ); + ev_io_start(EV_DEFAULT_UC_ &csio); + ev_unref(EV_DEFAULT_UC); +} + +void +luaA_cs_cleanup(void) +{ + if(csio.fd < 0) + return; + ev_ref(EV_DEFAULT_UC); + ev_io_stop(EV_DEFAULT_UC_ &csio); + if (close(csio.fd)) + warn("error closing UNIX domain socket: %s", strerror(errno)); + if(unlink(addr->sun_path)) + warn("error unlinking UNIX domain socket: %s", strerror(errno)); + p_delete(&addr); + csio.fd = -1; +} diff --git a/lua.h b/lua.h index 17f12a6dc..c420100a2 100644 --- a/lua.h +++ b/lua.h @@ -170,8 +170,9 @@ luaA_name_init(lua_State *L) void luaA_init(void); bool luaA_parserc(const char *); -void luaA_docmd(char *); void luaA_pushpointer(void *, awesome_type_t); +void luaA_cs_init(void); +void luaA_cs_cleanup(void); #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80