summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2007-01-20 22:32:04 +0000
committerMarcel Holtmann <marcel@holtmann.org>2007-01-20 22:32:04 +0000
commitce45df47b1a9a80f46cbb0ff1ae00308bf5046fa (patch)
tree36500868e3bd1c561919c2f45b76ceab16d0c386
parenta1566312330b71ffcb1cbead7a178e21d6c4cb14 (diff)
Handle multiple inotify event correctly
-rw-r--r--common/notify-inotify.c33
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;
}