diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2007-01-20 22:32:04 +0000 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2007-01-20 22:32:04 +0000 |
commit | ce45df47b1a9a80f46cbb0ff1ae00308bf5046fa (patch) | |
tree | 36500868e3bd1c561919c2f45b76ceab16d0c386 /common | |
parent | a1566312330b71ffcb1cbead7a178e21d6c4cb14 (diff) |
Handle multiple inotify event correctly
Diffstat (limited to 'common')
-rw-r--r-- | common/notify-inotify.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/common/notify-inotify.c b/common/notify-inotify.c index a35cf745..5672a4ed 100644 --- a/common/notify-inotify.c +++ b/common/notify-inotify.c @@ -50,30 +50,37 @@ static notify_func callback = NULL; static gboolean io_event(GIOChannel *chan, GIOCondition cond, gpointer data) { - unsigned char buf[129]; - struct inotify_event *evt = (struct inotify_event *) buf; - int len; + unsigned char buf[129], *ptr = buf; + gsize len; + GIOError err; if (cond & (G_IO_HUP | G_IO_ERR)) return FALSE; memset(buf, 0, sizeof(buf)); - len = read(fd, buf, sizeof(buf) - 1); - if (len < sizeof(struct inotify_event)) + err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf) - 1, &len); + if (err == G_IO_ERROR_AGAIN) return TRUE; - if (evt->wd != wd || !callback) - return TRUE; + while (len >= sizeof(struct inotify_event)) { + struct inotify_event *evt = (struct inotify_event *) ptr; + + if (evt->wd != wd || !callback) + continue; - if (evt->mask & (IN_CREATE | IN_MOVED_TO)) - callback(NOTIFY_CREATE, evt->name, NULL); + if (evt->mask & (IN_CREATE | IN_MOVED_TO)) + callback(NOTIFY_CREATE, evt->name, NULL); - if (evt->mask & (IN_DELETE | IN_MOVED_FROM)) - callback(NOTIFY_DELETE, evt->name, NULL); + if (evt->mask & (IN_DELETE | IN_MOVED_FROM)) + callback(NOTIFY_DELETE, evt->name, NULL); - if (evt->mask & IN_MODIFY) - callback(NOTIFY_MODIFY, evt->name, NULL); + if (evt->mask & IN_MODIFY) + callback(NOTIFY_MODIFY, evt->name, NULL); + + len -= sizeof(struct inotify_event) + evt->len; + ptr += sizeof(struct inotify_event) + evt->len; + } return TRUE; } |