ioloop-notify-inotify.c revision 9d7451b57769988f7e3e41cd8790e65429ffc5c7
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen/* Copyright (C) 2005 Johannes Berg */
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen#define INITIAL_INOTIFY_BUFLEN (FILENAME_MAX + sizeof(struct inotify_event))
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainenstatic int event_read_next(struct ioloop *ioloop)
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen if (ioctl(ctx->inotify_fd, FIONREAD, &required_bytes))
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen i_fatal("ioctl(inotify_fd, FIONREAD) failed: %m");
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen event = buffer_get_space_unsafe(ctx->buf, 0, required_bytes);
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen ret = read(ctx->inotify_fd, (void *)event, required_bytes);
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen if (gettimeofday(&ioloop_timeval, &ioloop_timezone) < 0)
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen while ((size_t)required_bytes > sizeof(*event)) {
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen for (io = ioloop->notifys; io != NULL; io = io->next) {
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen record_length = event->len + sizeof(struct inotify_event);
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen /* this might point outside the area if the loop
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen won't run again */
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainenstruct io *io_loop_notify_add(struct ioloop *ioloop, int fd,
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen ctx->event_io = io_add(ctx->inotify_fd, IO_READ,
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen /* now set up the notification request and shoot it off */
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen req.mask = IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE | IN_MODIFY;
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen watchdescriptor = ioctl(ctx->inotify_fd, INOTIFY_WATCH, &req);
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainenvoid io_loop_notify_remove(struct ioloop *ioloop, struct io *io)
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen for (io_p = &ioloop->notifys; *io_p != NULL; io_p = &(*io_p)->next) {
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen if (ioctl(ctx->inotify_fd, INOTIFY_IGNORE, &io->notify_context) < 0)
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainenvoid io_loop_notify_handler_init(struct ioloop *ioloop)
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen i_new(struct ioloop_notify_handler_context, 1);
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen ctx->inotify_fd = open("/dev/inotify", O_RDONLY);
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen ctx->buf = buffer_create_dynamic(default_pool, INITIAL_INOTIFY_BUFLEN);