summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Klauser <tklauser@distanz.ch>2007-01-20 13:47:53 +0100
committerTobias Klauser <tklauser@xenon.tklauser.home>2007-01-20 13:47:53 +0100
commit7fb27cb14e0761c8d746f3d6fe6b748570b29990 (patch)
treedd81e29ff3d10377252d603590f21c363b3102c7
parentf67d77663f9aa86baab6283c6ee96b6aee08b979 (diff)
inotail.c: Simplify iterating through inotify events
-rw-r--r--inotail.c30
1 files changed, 17 insertions, 13 deletions
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 <tklauser@distanz.ch>
+ * Copyright (C) 2005-2007, Tobias Klauser <tklauser@distanz.ch>
*
* 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;
}
}