Added inotify support for reloading Lua scripts automagically.
authorBrenden Matthews <brenden@rty.ca>
Wed, 20 May 2009 04:49:42 +0000 (22:49 -0600)
committerBrenden Matthews <brenden@rty.ca>
Wed, 20 May 2009 04:49:42 +0000 (22:49 -0600)
ChangeLog
src/conky.c
src/conky.h
src/imlib2.c
src/llua.c
src/llua.h

index 13f8a6d..a963f27 100644 (file)
--- 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
index bf2da2b..a34bf25 100644 (file)
@@ -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);
 
index 961140e..fde9ce4 100644 (file)
@@ -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
index 750c453..c61248a 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-#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;
index 61e3dac..4b17e22 100644 (file)
 #include "conky.h"
 #include "logging.h"
 
+#ifdef HAVE_SYS_INOTIFY_H
+#include <sys/inotify.h>
+
+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 */
+
index 763eb4f..d81a3a7 100644 (file)
@@ -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_*/