diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | inotail.c | 51 | ||||
-rw-r--r-- | inotail.h | 19 |
3 files changed, 41 insertions, 33 deletions
@@ -1,10 +1,10 @@ # Makefile for inotail # -# Copyright (C) 2006-2007 Tobias Klauser <tklauser@distanz.ch> +# Copyright (C) 2006-2008 Tobias Klauser <tklauser@distanz.ch> # # Licensed under the terms of the GNU General Public License; version 2 or later. -VERSION = 0.5 +VERSION = 0.6-pre0 # Paths prefix = /usr/local @@ -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-2007, Tobias Klauser <tklauser@distanz.ch> + * Copyright (C) 2005-2008, Tobias Klauser <tklauser@distanz.ch> * * The idea was taken from turbotail. * @@ -35,19 +35,14 @@ #include "inotify.h" #include "inotify-syscalls.h" - #include "inotail.h" #define PROGRAM_NAME "inotail" -/* 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; - /* Tailing relative to begin or end of file */ static char from_begin = 0; - /* Number of ignored files */ static int n_ignored = 0; @@ -67,7 +62,7 @@ static void *emalloc(size_t size) void *ret = malloc(size); if (unlikely(!ret)) { - fprintf(stderr, "Error: Failed to allocate %d bytes of memory (%s)\n", size, strerror(errno)); + fprintf(stderr, "Error: Failed to allocate %zu bytes of memory (%s)\n", size, strerror(errno)); exit(EXIT_FAILURE); } @@ -104,8 +99,10 @@ static void ignore_file(struct file_struct *f) close(f->fd); f->fd = -1; } - f->ignore = 1; - n_ignored++; + if (!f->ignore) { + f->ignore = 1; + n_ignored++; + } } static inline char *pretty_name(char *filename) @@ -480,7 +477,7 @@ out: return rc; } -static int tail_file(struct file_struct *f, unsigned long n_units, char mode, char forever) +static int tail_file(struct file_struct *f, unsigned long n_units, mode_t mode, char forever) { ssize_t bytes_read = 0; off_t offset = 0; @@ -566,33 +563,36 @@ static int handle_inotify_event(struct inotify_event *inev, struct file_struct * if (inev->mask & IN_MODIFY) { char *fbuf; - ssize_t rc; + ssize_t bytes_read; struct stat finfo; if (verbose) write_header(f->name); + if ((ret = fstat(f->fd, &finfo)) < 0) { + fprintf(stderr, "Error: Could not stat file '%s' (%s)\n", f->name, strerror(errno)); + goto ignore; + } + + /* Regular file got truncated */ + if (S_ISREG(finfo.st_mode) && finfo.st_size < f->size) { + fprintf(stderr, "File '%s' truncated\n", f->name); + f->size = finfo.st_size; + } + /* Seek to old file size */ - if (lseek(f->fd, f->size, SEEK_SET) == (off_t) -1) { + if ((ret = lseek(f->fd, f->size, SEEK_SET)) == (off_t) -1) { fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno)); - ret = -1; goto ignore; } fbuf = emalloc(f->blksize); - while ((rc = read(f->fd, fbuf, f->blksize)) != 0) - write(STDOUT_FILENO, fbuf, (size_t) rc); - - if (fstat(f->fd, &finfo) < 0) { - fprintf(stderr, "Error: Could not stat file '%s' (%s)\n", f->name, strerror(errno)); - ret = -1; - free(fbuf); - goto ignore; + while ((bytes_read = read(f->fd, fbuf, f->blksize)) != 0) { + write(STDOUT_FILENO, fbuf, (size_t) bytes_read); + f->size += bytes_read; } - f->size = finfo.st_size; - free(fbuf); return ret; } else if (inev->mask & IN_DELETE_SELF) { @@ -602,6 +602,8 @@ static int handle_inotify_event(struct inotify_event *inev, struct file_struct * return 0; } else if (inev->mask & IN_UNMOUNT) { fprintf(stderr, "Device containing file '%s' unmounted.\n", f->name); + } else if (inev->mask & IN_IGNORED) { + return 0; } ignore: @@ -686,7 +688,8 @@ int main(int argc, char **argv) int i, c, ret = 0; int n_files; unsigned long n_units = DEFAULT_N_LINES; - char forever = 0, mode = M_LINES; + mode_t mode = M_LINES; + char forever = 0; char **filenames; struct file_struct *files = NULL; @@ -8,11 +8,16 @@ #define _INOTAIL_H #include <sys/types.h> +#include "inotify.h" #define DEFAULT_N_LINES 10 /* Number of items to tail. */ +#define DEFAULT_BUFFER_SIZE 4096 +/* inotify event buffer length for one file */ +#define INOTIFY_BUFLEN (4 * sizeof(struct inotify_event)) + /* tail modes */ -enum { M_LINES, M_BYTES }; +typedef enum { M_LINES, M_BYTES } mode_t; /* Every tailed file is represented as a file_struct */ struct file_struct { @@ -48,16 +53,16 @@ struct char_buf { #define is_digit(c) ((c) >= '0' && (c) <= '9') -#ifdef DEBUG -# define dprintf(fmt, args...) fprintf(stderr, fmt, ##args) -#else -# define dprintf(fmt, args...) -#endif /* DEBUG */ - #ifdef __GNUC__ # define unlikely(x) __builtin_expect(!!(x), 0) #else # define unlikely(x) (x) #endif /* __GNUC__ */ +#ifdef DEBUG +# define dprintf(fmt, args...) fprintf(stderr, fmt, ##args) +#else +# define dprintf(fmt, args...) +#endif /* DEBUG */ + #endif /* _INOTAIL_H */ |