diff options
author | Tobias Klauser <tklauser@xenon.tklauser.home> | 2006-08-12 21:27:09 +0200 |
---|---|---|
committer | Tobias Klauser <tklauser@xenon.tklauser.home> | 2006-08-12 21:27:09 +0200 |
commit | 3c9d7963eec4c1a78583f70ba3a45b95e86064c9 (patch) | |
tree | afa2629da176806e3f00cc5d564cecc73862419a /inotail.c | |
parent | 10f6e1b387eaea5f373b088c4d880e9c938a5871 (diff) |
Introduce handling of ignored files
Files which are no longer available (e.g. moved, deleted) are marked as "ignore" and do no longer influence the tailing of other files.
Diffstat (limited to 'inotail.c')
-rw-r--r-- | inotail.c | 40 |
1 files changed, 30 insertions, 10 deletions
@@ -57,6 +57,14 @@ static void usage(int status) exit(status); } +static void setup_file(struct file_struct *f) +{ + f->fd = -1; + f->st_size = 0; + f->ignore = 0; + f->i_watch = -1; +} + static void write_header(const char *filename) { static unsigned short first_file = 1; @@ -159,7 +167,7 @@ static int tail_file(struct file_struct *f, int n_lines, char mode) static int watch_files(struct file_struct *f, int n_files) { - int ifd, i; + int ifd, i, n_ignored = 0; off_t offset; struct inotify_event *inev; char buf[sizeof(struct inotify_event) * 32]; /* Let's hope we don't get more than 32 events at a time */ @@ -171,14 +179,16 @@ static int watch_files(struct file_struct *f, int n_files) } for (i = 0; i < n_files; i++) { - f[i].i_watch = inotify_add_watch(ifd, f[i].name, + if (!f[i].ignore) + f[i].i_watch = inotify_add_watch(ifd, f[i].name, IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT); - dprintf(" Watch (%d) added to '%s' (%d)\n", f[i].i_watch, f[i].name, i); + else + n_ignored++; } memset(&buf, 0, sizeof(buf)); - while (1) { + while (n_ignored < n_files) { int len; len = read(ifd, buf, sizeof(buf)); @@ -189,12 +199,14 @@ static int watch_files(struct file_struct *f, int n_files) /* Which file has produced the event? */ for (i = 0; i < n_files; i++) { - if (f[i].i_watch == inev->wd) { + if (!f[i].ignore && f[i].i_watch == inev->wd) { fil = &f[i]; break; } } + /* XXX: Is it possible that no file in the list produced the event? */ + if (inev->mask & IN_MODIFY) { int block_size; char fbuf[BUFFER_SIZE]; @@ -207,13 +219,15 @@ static int watch_files(struct file_struct *f, int n_files) fil->fd = open(fil->name, O_RDONLY); if (fil->fd < 0) { + fil->ignore = 1; + n_ignored++; fprintf(stderr, "Error: Could not open file '%s' (%s)\n", f->name, strerror(errno)); - return -1; } if (fstat(fil->fd, &finfo) < 0) { + fil->ignore = 1; + n_ignored++; fprintf(stderr, "Error: Could not stat file '%s' (%s)\n", f->name, strerror(errno)); - return -1; } fil->st_size = finfo.st_size; @@ -242,23 +256,28 @@ static int watch_files(struct file_struct *f, int n_files) } if (inev->mask & IN_DELETE_SELF) { + fil->ignore = 1; + n_ignored++; fprintf(stderr, "File '%s' deleted.\n", fil->name); - return -1; } if (inev->mask & IN_MOVE_SELF) { + fil->ignore = 1; + n_ignored++; fprintf(stderr, "File '%s' moved.\n", fil->name); /* TODO: Try to follow file/fd */ - return -1; } if (inev->mask & IN_UNMOUNT) { + fil->ignore = 1; + n_ignored++; fprintf(stderr, "Device containing file '%s' unmounted.\n", fil->name); - return -1; } len -= sizeof(struct inotify_event) + inev->len; inev = (struct inotify_event *) ((char *) inev + sizeof(struct inotify_event) + inev->len); } } + + return -1; } int main(int argc, char **argv) @@ -312,6 +331,7 @@ int main(int argc, char **argv) files = malloc(n_files * sizeof(struct file_struct)); for (i = 0; i < n_files; i++) { files[i].name = filenames[i]; + setup_file(&files[i]); ret = tail_file(&files[i], n_lines, mode); if (ret < 0) files[i].ignore = 1; |