From 7fb27cb14e0761c8d746f3d6fe6b748570b29990 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sat, 20 Jan 2007 13:47:53 +0100 Subject: inotail.c: Simplify iterating through inotify events --- inotail.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'inotail.c') diff --git a/inotail.c b/inotail.c index 81864b5..dbb95eb 100644 --- a/inotail.c +++ b/inotail.c @@ -3,7 +3,7 @@ * A fast implementation of tail which uses the inotify API present in * recent versions of the Linux kernel. * - * Copyright (C) 2005-2006, Tobias Klauser + * Copyright (C) 2005-2007, Tobias Klauser * * The idea was taken from turbotail. * @@ -40,6 +40,8 @@ #define PROGRAM_NAME "inotail" #define BUFFER_SIZE 4096 +/* inotify event buffer length for one file */ +#define INOTIFY_BUFLEN (4 * sizeof(struct inotify_event)) /* Print header with filename before tailing the file? */ static char verbose = 0; @@ -337,9 +339,7 @@ ignore: static int watch_files(struct file_struct *files, int n_files) { int ifd, i; - unsigned buflen = 2 * n_files * sizeof(struct inotify_event); - struct inotify_event *inev; - char *buf; + char buf[n_files * INOTIFY_BUFLEN]; ifd = inotify_init(); if (ifd < 0) { @@ -353,24 +353,29 @@ static int watch_files(struct file_struct *files, int n_files) IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT); if (files[i].i_watch < 0) { - fprintf(stderr, "Error: Could not create inotify watch on file '%s' (%s)\n", files[i].name, strerror(errno)); + fprintf(stderr, "Error: Could not create inotify watch on file '%s' (%s)\n", + files[i].name, strerror(errno)); ignore_file(&files[i]); } } } - buf = malloc(buflen); - memset(buf, 0, buflen); - while (n_ignored < n_files) { ssize_t len; + int ev_idx = 0; - len = read(ifd, buf, buflen); - inev = (struct inotify_event *) buf; + len = read(ifd, buf, (n_files * INOTIFY_BUFLEN)); + if (len < 0) { + fprintf(stderr, "Error: Could not read inotify events (%s)\n", strerror(errno)); + exit(EXIT_FAILURE); + } - while (len > 0) { + while (ev_idx < len) { + struct inotify_event *inev; struct file_struct *f = NULL; + inev = (struct inotify_event *) &buf[ev_idx]; + /* Which file has produced the event? */ for (i = 0; i < n_files; i++) { if (!files[i].ignore && files[i].fd >= 0 && files[i].i_watch == inev->wd) { @@ -383,8 +388,7 @@ static int watch_files(struct file_struct *files, int n_files) break; handle_inotify_event(inev, f); - len -= sizeof(struct inotify_event) + inev->len; - inev = (struct inotify_event *) ((char *) inev + sizeof(struct inotify_event) + inev->len); + ev_idx += (n_files * INOTIFY_BUFLEN) + inev->len; } } -- cgit v1.2.3-54-g00ecf