From 011e52650b9765bc9464c67064f2bcdb6c58fbc5 Mon Sep 17 00:00:00 2001 From: Brenden Matthews Date: Tue, 19 May 2009 22:49:42 -0600 Subject: [PATCH] Added inotify support for reloading Lua scripts automagically. --- ChangeLog | 1 + src/conky.c | 22 ++++++++++---- src/conky.h | 1 + src/imlib2.c | 4 +-- src/llua.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/llua.h | 3 ++ 6 files changed, 115 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 13f8a6d..a963f27 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2009-05-19 * Added inotify support to reload the config when modified automatically on systems that support it + * Added inotify support for reloading Lua scripts automagically 2009-05-17 * Added support for the Lua programming language diff --git a/src/conky.c b/src/conky.c index bf2da2b..a34bf25 100644 --- a/src/conky.c +++ b/src/conky.c @@ -6396,19 +6396,23 @@ static void update_text(void) need_to_update = 1; } +#ifdef HAVE_SYS_INOTIFY_H +int inotify_fd; +#endif + static void main_loop(void) { #ifdef SIGNAL_BLOCKING sigset_t newmask, oldmask; #endif + double t; #ifdef HAVE_SYS_INOTIFY_H - int inotify_fd = 0, inotify_config_wd = 0; + int inotify_config_wd = 0; #define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event)) #define INOTIFY_BUF_LEN (20 * (INOTIFY_EVENT_SIZE + 16)) char inotify_buff[INOTIFY_BUF_LEN]; #endif /* HAVE_SYS_INOTIFY_H */ - double t; #ifdef SIGNAL_BLOCKING sigemptyset(&newmask); @@ -6729,12 +6733,12 @@ static void main_loop(void) break; } #ifdef HAVE_SYS_INOTIFY_H - if (!inotify_fd) { - inotify_fd = inotify_init(); + if (!inotify_config_wd) { inotify_config_wd = inotify_add_watch(inotify_fd, current_config, IN_MODIFY); - } else if (inotify_fd && inotify_config_wd) { + } + if (inotify_fd && inotify_config_wd) { int len = 0, idx = 0; fd_set descriptors; struct timeval time_to_wait; @@ -6762,6 +6766,11 @@ static void main_loop(void) IN_MODIFY); } } +#ifdef HAVE_LUA + else { + llua_inotify_query(ev->wd, ev->mask); + } +#endif /* HAVE_LUA */ idx += INOTIFY_EVENT_SIZE + ev->len; } } @@ -8379,6 +8388,9 @@ int main(int argc, char **argv) #endif /* ! CONF_OUTPUT */ } } +#ifdef HAVE_SYS_INOTIFY_H + inotify_fd = inotify_init(); +#endif /* HAVE_SYS_INOTIFY_H */ load_config_file(current_config); diff --git a/src/conky.h b/src/conky.h index 961140e..fde9ce4 100644 --- a/src/conky.h +++ b/src/conky.h @@ -315,6 +315,7 @@ extern double current_update_time, last_update_time, update_interval; /* defined in conky.c */ int spaced_print(char *, int, const char *, int, ...) __attribute__((format(printf, 3, 5))); +extern int inotify_fd; #define TO_X 1 #define TO_STDOUT 2 diff --git a/src/imlib2.c b/src/imlib2.c index 750c453..c61248a 100644 --- a/src/imlib2.c +++ b/src/imlib2.c @@ -28,10 +28,8 @@ #include #include -#define NAME_SIZE 1024 - struct image_list_s { - char name[NAME_SIZE]; + char name[DEFAULT_TEXT_BUFFER_SIZE]; Imlib_Image image; int x, y, w, h; int wh_set; diff --git a/src/llua.c b/src/llua.c index 61e3dac..4b17e22 100644 --- a/src/llua.c +++ b/src/llua.c @@ -28,6 +28,14 @@ #include "conky.h" #include "logging.h" +#ifdef HAVE_SYS_INOTIFY_H +#include + +void llua_append_notify(const char *name); +void llua_rm_notifies(void); +static int llua_block_notify = 0; +#endif /* HAVE_SYS_INOTIFY_H */ + lua_State *lua_L = NULL; void llua_init(void) @@ -45,6 +53,8 @@ void llua_load(const char *script) if (error) { ERR("llua_load: %s", lua_tostring(lua_L, -1)); lua_pop(lua_L, 1); + } else if (!llua_block_notify) { + llua_append_notify(script); } } @@ -176,7 +186,89 @@ int llua_getinteger(const char *args, int *per) void llua_close(void) { + llua_rm_notifies(); if(!lua_L) return; lua_close(lua_L); lua_L = NULL; } + +#ifdef HAVE_SYS_INOTIFY_H +struct _lua_notify_s { + int wd; + char name[DEFAULT_TEXT_BUFFER_SIZE]; + struct _lua_notify_s *next; +}; +static struct _lua_notify_s *lua_notifies = 0; + +static struct _lua_notify_s *llua_notify_list_do_alloc(const char *name) +{ + struct _lua_notify_s *ret = malloc(sizeof(struct _lua_notify_s)); + memset(ret, 0, sizeof(struct _lua_notify_s)); + strncpy(ret->name, name, DEFAULT_TEXT_BUFFER_SIZE); + return ret; +} + +void llua_append_notify(const char *name) +{ + /* do it */ + struct _lua_notify_s *new_tail = 0; + if (!lua_notifies) { + /* empty, fresh new digs */ + new_tail = lua_notifies = llua_notify_list_do_alloc(name); + } else { + struct _lua_notify_s *tail = lua_notifies; + while (tail->next) { + tail = tail->next; + } + // should be @ the end now + new_tail = llua_notify_list_do_alloc(name); + tail->next = new_tail; + } + new_tail->wd = inotify_add_watch(inotify_fd, + new_tail->name, + IN_MODIFY); +} + +void llua_rm_notifies(void) +{ + /* git 'er done */ + struct _lua_notify_s *head = lua_notifies; + struct _lua_notify_s *next = head->next; + if (!lua_notifies) return; + inotify_rm_watch(inotify_fd, head->wd); + free(head); + while (next) { + head = next; + next = head->next; + inotify_rm_watch(inotify_fd, head->wd); + free(head); + } + lua_notifies = 0; +} + +void llua_inotify_query(int wd, int mask) +{ + struct _lua_notify_s *head = lua_notifies; + if (mask & IN_MODIFY || mask & IN_IGNORED) { + /* for whatever reason, i keep getting IN_IGNORED when the file is + * modified */ + while (head) { + if (head->wd == wd) { + llua_block_notify = 1; + llua_load(head->name); + llua_block_notify = 0; + if (mask & IN_IGNORED) { + /* for some reason we get IN_IGNORED here + * sometimes, so we need to re-add the watch */ + head->wd = inotify_add_watch(inotify_fd, + head->name, + IN_MODIFY); + } + return; + } + head = head->next; + } + } +} +#endif /* HAVE_SYS_INOTIFY_H */ + diff --git a/src/llua.h b/src/llua.h index 763eb4f..d81a3a7 100644 --- a/src/llua.h +++ b/src/llua.h @@ -38,5 +38,8 @@ char *llua_getstring(const char *args); char *llua_getstring_read(const char *function, const char *arg); int llua_getinteger(const char *args, int *per); void llua_close(void); +#ifdef HAVE_SYS_INOTIFY_H +void llua_inotify_query(int wd, int mask); +#endif /* HAVE_SYS_INOTIFY_H */ #endif /* LUA_H_*/ -- 1.7.9.5