summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--inotail.c51
-rw-r--r--inotail.h19
3 files changed, 41 insertions, 33 deletions
diff --git a/Makefile b/Makefile
index cfa1402..34a6041 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/inotail.c b/inotail.c
index 483306e..7e2b6ac 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-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;
diff --git a/inotail.h b/inotail.h
index 5029540..ea680cb 100644
--- a/inotail.h
+++ b/inotail.h
@@ -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 */