ioloop-notify-inotify.c revision 36d2b3dc8766ef336a289a51075ca2f3236ef1ef
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen/* Copyright (C) 2005 Johannes Berg */
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen#define INITIAL_INOTIFY_BUFLEN (FILENAME_MAX + sizeof(struct inotify_event))
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenstatic bool 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) {
283ccfe110ed62e48f36e0d84e47da8cae5106beTimo Sirainen struct inotify_io *iio = (struct inotify_io *)io;
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 */
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainenstatic void event_callback(struct ioloop *ioloop)
6246b93fb37890dcb2f4df9896438f3f376ab284Timo Sirainenstruct io *io_loop_notify_add(struct ioloop *ioloop, const char *path,
6246b93fb37890dcb2f4df9896438f3f376ab284Timo Sirainen watchdescriptor = inotify_add_watch(ctx->inotify_fd, path,
36d2b3dc8766ef336a289a51075ca2f3236ef1efTimo Sirainen /* ESTALE could happen with NFS. Don't bother giving an error
36d2b3dc8766ef336a289a51075ca2f3236ef1efTimo Sirainen message then. */
36d2b3dc8766ef336a289a51075ca2f3236ef1efTimo Sirainen i_error("inotify_add_watch(%s) failed: %m", path);
d6500661eb699ff335ac570c8646b6e067e1aac6Timo Sirainen ctx->event_io = io_add(ctx->inotify_fd, IO_READ,
283ccfe110ed62e48f36e0d84e47da8cae5106beTimo Sirainen io = p_new(ioloop->pool, struct inotify_io, 1);
283ccfe110ed62e48f36e0d84e47da8cae5106beTimo Sirainenvoid io_loop_notify_remove(struct ioloop *ioloop, struct io *_io)
283ccfe110ed62e48f36e0d84e47da8cae5106beTimo Sirainen struct inotify_io *io = (struct inotify_io *)_io;
283ccfe110ed62e48f36e0d84e47da8cae5106beTimo Sirainen if (inotify_rm_watch(ctx->inotify_fd, io->wd) < 0)
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainenvoid io_loop_notify_handler_init(struct ioloop *ioloop)
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen i_new(struct ioloop_notify_handler_context, 1);
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainen ctx->buf = buffer_create_dynamic(default_pool, INITIAL_INOTIFY_BUFLEN);
9d7451b57769988f7e3e41cd8790e65429ffc5c7Timo Sirainenvoid io_loop_notify_handler_deinit(struct ioloop *ioloop)
6246b93fb37890dcb2f4df9896438f3f376ab284Timo Sirainen i_error("close(inotify descriptor) failed: %m");