summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Klauser <tklauser@distanz.ch>2007-04-18 12:28:08 +0200
committerTobias Klauser <tklauser@xenon.tklauser.home>2007-04-18 12:28:08 +0200
commitad7e695784296d9e4058ebe5e27a20864076f53b (patch)
tree7f64de06f67014e85c8c8d6775f5cdd36297049d
parentdc080389b64a88ac58385642e5388fc9763be575 (diff)
Update sourec for inotail 0.30.3-1
-rw-r--r--Makefile29
-rw-r--r--README17
-rw-r--r--changelog9
-rw-r--r--inotail.12
-rw-r--r--inotail.c293
-rw-r--r--inotail.h11
-rw-r--r--inotify-syscalls.h32
7 files changed, 223 insertions, 170 deletions
diff --git a/Makefile b/Makefile
index 13b67c3..cfeb89a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,21 +1,20 @@
# Makefile for inotail
#
-# Copyright (C) 2006, Tobias Klauser <tklauser@distanz.ch>
+# Copyright (C) 2006-2007 Tobias Klauser <tklauser@distanz.ch>
#
# Licensed under the terms of the GNU General Public License; version 2 or later.
-VERSION = 0.2
+VERSION = 0.3
# Paths
-prefix = /usr
-DESTDIR =
+prefix = /usr/local
+BINDIR = $(prefix)/bin
+MANDIR = $(prefix)/share/man/man1
-CC := gcc
-CFLAGS := -Wall -pipe -D_USE_SOURCE -DVERSION="\"$(VERSION)\""
-WARN := -Wstrict-prototypes -Wsign-compare -Wshadow \
- -Wchar-subscripts -Wmissing-declarations -Wnested-externs \
- -Wpointer-arith -Wcast-align -Wmissing-prototypes
-CFLAGS += $(WARN)
+CC := gcc
+CFLAGS := $(CFLAGS) -W -Wall -pipe -D_USE_SOURCE -DVERSION="\"$(VERSION)\"" \
+ -Wstrict-prototypes -Wsign-compare -Wshadow -Wchar-subscripts \
+ -Wmissing-declarations -Wpointer-arith -Wcast-align -Wmissing-prototypes
# Compile with 'make DEBUG=true' to enable debugging
DEBUG = false
@@ -23,22 +22,22 @@ ifeq ($(strip $(DEBUG)),true)
CFLAGS += -g -DDEBUG
endif
-all: Makefile inotail
+all: inotail
inotail: inotail.o
%.o: %.c %.h
$(CC) $(CFLAGS) -c $< -o $@
install: inotail
- install -m 775 -D inotail $(DESTDIR)$(prefix)/bin/inotail
- install -m 644 -D inotail.1 $(DESTDIR)$(prefix)/share/man/man1/inotail.1
+ install -m 775 -D inotail $(BINDIR)/inotail
+ install -m 644 -D inotail.1 $(MANDIR)/inotail.1
cscope:
cscope -b
release:
- git-archive --format=tar --prefix=inotail-0.2/ HEAD | gzip -9v > ../inotail-$(VERSION).tar.gz
- git-archive --format=tar --prefix=inotail-0.2/ HEAD | bzip2 -9v > ../inotail-$(VERSION).tar.bz2
+ git-archive --format=tar --prefix=inotail-$(VERSION)/ HEAD | gzip -9v > ../inotail-$(VERSION).tar.gz
+ git-archive --format=tar --prefix=inotail-$(VERSION)/ HEAD | bzip2 -9v > ../inotail-$(VERSION).tar.bz2
clean:
rm -f inotail *.o cscope.*
diff --git a/README b/README
index 7c13988..577584e 100644
--- a/README
+++ b/README
@@ -15,6 +15,23 @@ Requirements
------------
- Linux kernel 2.6.13 or higher with CONFIG_INOTIFY enabled
- Standard C Library (tested with GNU libc but might work with others too)
+- GCC (other compilers might work but are not tested)
+
+Building and installing inotail
+-------------------------------
+To build inotail type:
+
+ $ make
+
+By default, inotail is installed to /usr/local/bin/, the manpage is installed to
+/usr/local/share/man/man1/. To install the inotail files to these locations type:
+
+ $ make install
+
+To change these locations just set the prefix variable. E.g. to install the
+inotail binary to /usr/ and the manpage to /usr/share/man/ respectively type:
+
+ $ make prefix=/usr install
License
-------
diff --git a/changelog b/changelog
index 5e161ff..8af070a 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,12 @@
+inotail 0.3
+
+ * Follow files even if they were moved
+ * Fix a problem when tailing more than 4096 bytes/chars at once
+ * Only print the filename once when the -v option is specified
+ * Various small fixes and cleanups
+
+ -- Tobias Klauser <tklauser@distanz.ch> 2007-04-17 13:44
+
inotail 0.2
* Support for the -n/-c +<num> options (tail relative to start of file)
diff --git a/inotail.1 b/inotail.1
index 2c19ac3..d543e52 100644
--- a/inotail.1
+++ b/inotail.1
@@ -39,7 +39,7 @@ keep the file(s) open and print appended data as the file grows
.TP
.B \-n \fIN\fR, \fB\-\-lines\fR=\fIN\fR
output the last N lines (default: 10) If the first character of N is a '+',
-begin printing with with the Nth line from the start of each file.
+begin printing with the Nth line from the start of each file.
.TP
.B \-v, \fB\-\-verbose
print headers with file names
diff --git a/inotail.c b/inotail.c
index 7b58477..6f8be7c 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.
*
@@ -30,6 +30,7 @@
#include <fcntl.h>
#include <errno.h>
#include <getopt.h>
+#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -40,10 +41,8 @@
#define PROGRAM_NAME "inotail"
#define BUFFER_SIZE 4096
-
-/* (ino)tail works on these file types */
-#define IS_TAILABLE(mode) \
- (S_ISREG(mode) || S_ISFIFO(mode) || S_ISSOCK(mode) || S_ISCHR(mode))
+/* 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;
@@ -51,20 +50,23 @@ 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;
+
/* Command line options */
static const struct option long_opts[] = {
- {"bytes", required_argument, NULL, 'c'},
- {"follow", optional_argument, NULL, 'f'},
- {"lines", required_argument, NULL, 'n'},
- {"verbose", no_argument, NULL, 'v'},
- {"help", no_argument, NULL, 'h'},
- {"version", no_argument, NULL, 'V'},
- {NULL, 0, NULL, 0}
+ { "bytes", required_argument, NULL, 'c' },
+ { "follow", optional_argument, NULL, 'f' },
+ { "lines", required_argument, NULL, 'n' },
+ { "verbose", no_argument, NULL, 'v' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'V' },
+ { NULL, 0, NULL, 0 }
};
static void usage(const int status)
{
- fprintf(stderr, "Usage: %s [OPTION]... [FILE]...\n\n"
+ fprintf(stdout, "Usage: %s [OPTION]... [FILE]...\n\n"
" -c N, --bytes=N output the last N bytes\n"
" -f, --follow output as the file grows\n"
" -n N, --lines=N output the last N lines (default: %d)\n"
@@ -78,7 +80,7 @@ static void usage(const int status)
exit(status);
}
-static void setup_file(struct file_struct *f)
+static inline void setup_file(struct file_struct *f)
{
f->fd = -1;
f->st_size = 0;
@@ -86,30 +88,43 @@ static void setup_file(struct file_struct *f)
f->i_watch = -1;
}
+static void ignore_file(struct file_struct *f)
+{
+ if (f->fd != -1) {
+ close(f->fd);
+ f->fd = -1;
+ }
+ f->ignore = 1;
+ n_ignored++;
+}
+
static inline char *pretty_name(char *filename)
{
- return (strncmp(filename, "-", 1) == 0) ? "standard input" : filename;
+ return (strcmp(filename, "-") == 0) ? "standard input" : filename;
}
static void write_header(char *filename)
{
static unsigned short first_file = 1;
+ static char *last = NULL;
+
+ if (last != filename)
+ fprintf(stdout, "%s==> %s <==\n", (first_file ? "" : "\n"), pretty_name(filename));
- fprintf(stdout, "%s==> %s <==\n", (first_file ? "" : "\n"), pretty_name(filename));
first_file = 0;
+ last = filename;
}
-static off_t lines_to_offset_from_end(struct file_struct *f, unsigned int n_lines)
+static off_t lines_to_offset_from_end(struct file_struct *f, unsigned long n_lines)
{
char buf[BUFFER_SIZE];
off_t offset = f->st_size;
n_lines++; /* We also count the last \n */
- memset(&buf, 0, sizeof(buf));
while (offset > 0 && n_lines > 0) {
- int i, rc;
- int block_size = BUFFER_SIZE; /* Size of the current block we're reading */
+ int i;
+ ssize_t rc, block_size = BUFFER_SIZE; /* Size of the current block we're reading */
if (offset < BUFFER_SIZE)
block_size = offset;
@@ -120,28 +135,23 @@ static off_t lines_to_offset_from_end(struct file_struct *f, unsigned int n_line
lseek(f->fd, offset, SEEK_SET);
rc = read(f->fd, &buf, block_size);
- if (rc < 0) {
+ if (unlikely(rc < 0)) {
fprintf(stderr, "Error: Could not read from file '%s' (%s)\n", f->name, strerror(errno));
return -1;
}
- for (i = block_size; i > 0; i--) {
+ for (i = block_size - 1; i > 0; i--) {
if (buf[i] == '\n') {
- n_lines--;
-
- if (n_lines == 0) {
- offset += i + 1; /* We don't want the first \n */
- break;
- }
+ if (--n_lines == 0)
+ return offset += i + 1; /* We don't want the first \n */
}
}
}
return offset;
-
}
-static off_t lines_to_offset_from_begin(struct file_struct *f, unsigned int n_lines)
+static off_t lines_to_offset_from_begin(struct file_struct *f, unsigned long n_lines)
{
char buf[BUFFER_SIZE];
off_t offset = 0;
@@ -151,27 +161,24 @@ static off_t lines_to_offset_from_begin(struct file_struct *f, unsigned int n_li
return 0;
n_lines--;
- memset(&buf, 0, sizeof(buf));
while (offset <= f->st_size && n_lines > 0) {
- int i, rc;
- int block_size = BUFFER_SIZE;
+ int i;
+ ssize_t rc, block_size = BUFFER_SIZE;
lseek(f->fd, offset, SEEK_SET);
rc = read(f->fd, &buf, block_size);
- if (rc < 0) {
+ if (unlikely(rc < 0)) {
fprintf(stderr, "Error: Could not read from file '%s' (%s)\n", f->name, strerror(errno));
return -1;
- }
+ } else if (rc < block_size)
+ block_size = rc;
for (i = 0; i < block_size; i++) {
if (buf[i] == '\n') {
- n_lines--;
- if (n_lines == 0) {
- offset += i + 1;
- return offset;
- }
+ if (--n_lines == 0)
+ return offset + i + 1;
}
}
@@ -181,7 +188,7 @@ static off_t lines_to_offset_from_begin(struct file_struct *f, unsigned int n_li
return offset;
}
-static off_t lines_to_offset(struct file_struct *f, unsigned int n_lines)
+static off_t lines_to_offset(struct file_struct *f, unsigned long n_lines)
{
if (from_begin)
return lines_to_offset_from_begin(f, n_lines);
@@ -189,18 +196,25 @@ static off_t lines_to_offset(struct file_struct *f, unsigned int n_lines)
return lines_to_offset_from_end(f, n_lines);
}
-static inline off_t bytes_to_offset(struct file_struct *f, unsigned int n_bytes)
+static off_t bytes_to_offset(struct file_struct *f, unsigned long n_bytes)
{
+ off_t offset = 0;
+
/* tail everything for 'inotail -c +0' */
- if (from_begin && n_bytes == 0)
- return 0;
- else
- return (from_begin ? ((off_t) n_bytes - 1) : (f->st_size - (off_t) n_bytes));
+ if (from_begin) {
+ if (n_bytes > 0)
+ offset = (off_t) n_bytes - 1;
+ } else {
+ if ((off_t) n_bytes < f->st_size)
+ offset = f->st_size - (off_t) n_bytes;
+ }
+
+ return offset;
}
-static int tail_pipe(struct file_struct *f)
+static ssize_t tail_pipe(struct file_struct *f)
{
- int rc;
+ ssize_t rc;
char buf[BUFFER_SIZE];
if (verbose)
@@ -213,36 +227,38 @@ static int tail_pipe(struct file_struct *f)
return rc;
}
-static int tail_file(struct file_struct *f, unsigned int n_units, char mode)
+static int tail_file(struct file_struct *f, unsigned long n_units, char mode, char forever)
{
- int ret = -1;
ssize_t bytes_read = 0;
off_t offset = 0;
char buf[BUFFER_SIZE];
struct stat finfo;
- if (strncmp(f->name, "-", 1) == 0)
+ if (strcmp(f->name, "-") == 0)
f->fd = STDIN_FILENO;
else {
f->fd = open(f->name, O_RDONLY);
- if (f->fd < 0) {
+ if (unlikely(f->fd < 0)) {
fprintf(stderr, "Error: Could not open file '%s' (%s)\n", f->name, strerror(errno));
+ ignore_file(f);
return -1;
}
}
if (fstat(f->fd, &finfo) < 0) {
fprintf(stderr, "Error: Could not stat file '%s' (%s)\n", f->name, strerror(errno));
- goto out;
+ ignore_file(f);
+ return -1;
}
if (!IS_TAILABLE(finfo.st_mode)) {
fprintf(stderr, "Error: '%s' of unsupported file type\n", f->name);
- goto out;
+ ignore_file(f);
+ return -1;
}
- /* We cannot seek on these */
- if (S_ISFIFO(finfo.st_mode) || S_ISSOCK(finfo.st_mode) || f->fd == STDIN_FILENO)
+ /* Cannot seek on these */
+ if (IS_PIPELIKE(finfo.st_mode) || f->fd == STDIN_FILENO)
return tail_pipe(f);
f->st_size = finfo.st_size;
@@ -253,8 +269,10 @@ static int tail_file(struct file_struct *f, unsigned int n_units, char mode)
offset = bytes_to_offset(f, n_units);
/* We only get negative offsets on errors */
- if (offset < 0)
- goto out;
+ if (unlikely(offset < 0)) {
+ ignore_file(f);
+ return -1;
+ }
if (verbose)
write_header(f->name);
@@ -264,132 +282,129 @@ static int tail_file(struct file_struct *f, unsigned int n_units, char mode)
while ((bytes_read = read(f->fd, &buf, BUFFER_SIZE)) > 0)
write(STDOUT_FILENO, buf, (size_t) bytes_read);
- ret = 0;
-out:
- if (close(f->fd) < 0) {
- fprintf(stderr, "Error: Could not close file '%s' (%s)\n", f->name, strerror(errno));
- ret = -1;
- }
+ if (!forever) {
+ if (close(f->fd) < 0) {
+ fprintf(stderr, "Error: Could not close file '%s' (%s)\n", f->name, strerror(errno));
+ return -1;
+ }
+ } /* Let the fd open otherwise, we'll need it */
- return ret;
+ return 0;
}
-static int handle_inotify_event(struct inotify_event *inev, struct file_struct *fil, int n_ignored)
+static int handle_inotify_event(struct inotify_event *inev, struct file_struct *f)
{
- off_t offset;
+ int ret = 0;
if (inev->mask & IN_MODIFY) {
- int rc;
+ ssize_t rc;
char fbuf[BUFFER_SIZE];
struct stat finfo;
- fil->fd = open(fil->name, O_RDONLY);
- if (fil->fd < 0) {
- fprintf(stderr, "Error: Could not open file '%s' (%s)\n", fil->name, strerror(errno));
- goto ignore;
- }
-
- if (fstat(fil->fd, &finfo) < 0) {
- fprintf(stderr, "Error: Could not stat file '%s' (%s)\n", fil->name, strerror(errno));
- close(fil->fd);
- goto ignore;
- }
-
- offset = fil->st_size;
- fil->st_size = finfo.st_size;
-
if (verbose)
- write_header(fil->name);
+ write_header(f->name);
- memset(&fbuf, 0, sizeof(fbuf));
+ lseek(f->fd, f->st_size, SEEK_SET); /* Old file size */
+ while ((rc = read(f->fd, &fbuf, BUFFER_SIZE)) != 0)
+ write(STDOUT_FILENO, fbuf, (size_t) rc);
- lseek(fil->fd, offset, SEEK_SET);
- while ((rc = read(fil->fd, &fbuf, BUFFER_SIZE)) != 0)
- write(STDOUT_FILENO, fbuf, rc);
+ if (fstat(f->fd, &finfo) < 0) {
+ fprintf(stderr, "Error: Could not stat file '%s' (%s)\n", f->name, strerror(errno));
+ ret = -1;
+ goto ignore;
+ }
- close(fil->fd);
+ f->st_size = finfo.st_size;
- return n_ignored;
+ return ret;
} else if (inev->mask & IN_DELETE_SELF) {
- fprintf(stderr, "File '%s' deleted.\n", fil->name);
+ fprintf(stderr, "File '%s' deleted.\n", f->name);
} else if (inev->mask & IN_MOVE_SELF) {
- /* TODO: Try to follow file/fd */
- fprintf(stderr, "File '%s' moved.\n", fil->name);
+ fprintf(stderr, "File '%s' moved.\n", f->name);
+ return 0;
} else if (inev->mask & IN_UNMOUNT) {
- fprintf(stderr, "Device containing file '%s' unmounted.\n", fil->name);
+ fprintf(stderr, "Device containing file '%s' unmounted.\n", f->name);
}
ignore:
- fil->ignore = 1;
- n_ignored++;
+ ignore_file(f);
- return n_ignored;
+ return ret;
}
-static int watch_files(struct file_struct *f, int n_files)
+static int watch_files(struct file_struct *files, int n_files)
{
- int ifd, i, n_ignored = 0;
- unsigned buflen = 2 * n_files * sizeof(struct inotify_event);
- struct inotify_event *inev;
- char *buf;
+ int ifd, i;
+ char buf[n_files * INOTIFY_BUFLEN];
ifd = inotify_init();
- if (ifd < 0) {
+ if (errno == ENOSYS) {
fprintf(stderr, "Error: Inotify is not supported by the kernel you're currently running.\n");
exit(EXIT_FAILURE);
+ } else if (unlikely(ifd < 0)) {
+ fprintf(stderr, "Error: Could not initialize Inotify (%s)\n", strerror(errno));
+ exit(EXIT_FAILURE);
}
for (i = 0; i < n_files; i++) {
- if (!f[i].ignore)
- f[i].i_watch = inotify_add_watch(ifd, f[i].name,
+ if (!files[i].ignore) {
+ files[i].i_watch = inotify_add_watch(ifd, files[i].name,
IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT);
- else
- n_ignored++;
- }
- buf = malloc(buflen);
- memset(buf, 0, buflen);
+ if (files[i].i_watch < 0) {
+ fprintf(stderr, "Error: Could not create inotify watch on file '%s' (%s)\n",
+ files[i].name, strerror(errno));
+ ignore_file(&files[i]);
+ }
+ }
+ }
while (n_ignored < n_files) {
- int len;
+ 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 (unlikely(len < 0)) {
+ fprintf(stderr, "Error: Could not read inotify events (%s)\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ while (ev_idx < len) {
+ struct inotify_event *inev;
+ struct file_struct *f = NULL;
- while (len > 0) {
- struct file_struct *fil = NULL;
+ inev = (struct inotify_event *) &buf[ev_idx];
/* Which file has produced the event? */
for (i = 0; i < n_files; i++) {
- if (!f[i].ignore && f[i].fd >= 0 && f[i].i_watch == inev->wd) {
- fil = &f[i];
+ if (!files[i].ignore && files[i].fd >= 0 && files[i].i_watch == inev->wd) {
+ f = &files[i];
break;
}
}
- if (unlikely(!fil))
+ if (unlikely(!f))
break;
- n_ignored = handle_inotify_event(inev, fil, n_ignored);
- len -= sizeof(struct inotify_event) + inev->len;
- inev = (struct inotify_event *) ((char *) inev + sizeof(struct inotify_event) + inev->len);
+ if (handle_inotify_event(inev, f) < 0)
+ break;
+ ev_idx += INOTIFY_BUFLEN + inev->len;
}
}
- free(buf);
close(ifd);
- return n_ignored;
+ return -1;
}
int main(int argc, char **argv)
{
int i, c, ret = 0;
- int n_files = 0;
- int n_units = DEFAULT_N_LINES;
+ int n_files;
+ unsigned long n_units = DEFAULT_N_LINES;
char forever = 0, mode = M_LINES;
char **filenames;
- struct file_struct *files;
+ struct file_struct *files = NULL;
while ((c = getopt_long(argc, argv, "c:n:fvVh", long_opts, NULL)) != -1) {
switch (c) {
@@ -397,13 +412,17 @@ int main(int argc, char **argv)
mode = M_BYTES;
/* fall through */
case 'n':
- if (*optarg == '+')
+ if (*optarg == '+') {
from_begin = 1;
- else if (*optarg == '-')
optarg++;
+ } else if (*optarg == '-')
+ optarg++;
+
+ if (!isdigit(*optarg)) {
+ fprintf(stderr, "Invalid number of lines: %s\n", optarg);
+ exit(EXIT_FAILURE);
+ }
n_units = strtoul(optarg, NULL, 0);
- if (n_units < 0)
- n_units = 0;
break;
case 'f':
forever = 1;
@@ -412,8 +431,8 @@ int main(int argc, char **argv)
verbose = 1;
break;
case 'V':
- fprintf(stderr, "%s %s\n", PROGRAM_NAME, VERSION);
- return 0;
+ fprintf(stdout, "%s %s\n", PROGRAM_NAME, VERSION);
+ exit(EXIT_SUCCESS);
case 'h':
usage(EXIT_SUCCESS);
default:
@@ -428,7 +447,7 @@ int main(int argc, char **argv)
} else {
/* It must be stdin then */
static char *dummy_stdin = "-";
- n_files++;
+ n_files = 1;
filenames = &dummy_stdin;
/* POSIX says that -f is ignored if no file operand is
@@ -436,13 +455,13 @@ int main(int argc, char **argv)
if (forever) {
struct stat finfo;
if (fstat(STDIN_FILENO, &finfo) == 0
- && (S_ISFIFO(finfo.st_mode) || S_ISSOCK(finfo.st_mode)))
+ && IS_PIPELIKE(finfo.st_mode))
forever = 0;
}
}
files = malloc(n_files * sizeof(struct file_struct));
- if (!files) {
+ if (unlikely(!files)) {
fprintf(stderr, "Error: Not enough memory (%s)\n", strerror(errno));
exit(EXIT_FAILURE);
}
@@ -450,9 +469,9 @@ int main(int argc, char **argv)
for (i = 0; i < n_files; i++) {
files[i].name = filenames[i];
setup_file(&files[i]);
- ret = tail_file(&files[i], n_units, mode);
+ ret = tail_file(&files[i], n_units, mode, forever);
if (ret < 0)
- files[i].ignore = 1;
+ ignore_file(&files[i]);
}
if (forever)
diff --git a/inotail.h b/inotail.h
index e1590df..4c57867 100644
--- a/inotail.h
+++ b/inotail.h
@@ -18,12 +18,17 @@ struct file_struct {
char *name; /* Name of file (or '-' for stdin) */
int fd; /* File descriptor (or -1 if file is not open */
off_t st_size; /* File size */
-
- unsigned ignore; /* Wheter to ignore the file in further processing */
-
+ unsigned ignore; /* Whether to ignore the file in further processing */
int i_watch; /* Inotify watch associated with file_struct */
};
+#define IS_PIPELIKE(mode) \
+ (S_ISFIFO(mode) || S_ISSOCK(mode))
+
+/* inotail works on these file types */
+#define IS_TAILABLE(mode) \
+ (S_ISREG(mode) || IS_PIPELIKE(mode) || S_ISCHR(mode))
+
#ifdef DEBUG
# define dprintf(fmt, args...) fprintf(stderr, fmt, ##args)
#else
diff --git a/inotify-syscalls.h b/inotify-syscalls.h
index a1d5408..69144cb 100644
--- a/inotify-syscalls.h
+++ b/inotify-syscalls.h
@@ -4,14 +4,15 @@
*
* Licensed under the terms of the GNU General Public License Version 2.
*
- * Copyright (c) 2006 Tobias Klauser <tklauser@distanz.ch>
+ * Copyright (c) 2006-2007 Tobias Klauser <tklauser@distanz.ch>
*/
#ifndef _LINUX_INOTIFY_SYSCALLS_H
#define _LINUX_INOTIFY_SYSCALLS_H
#include <sys/syscall.h>
-
+/* glibc already defines them for some architectures */
+#ifndef __NR_inotify_init
#if defined(__i386__)
# define __NR_inotify_init 291
# define __NR_inotify_add_watch 292
@@ -41,12 +42,6 @@
# define __NR_inotify_add_watch 152
# define __NR_inotify_rm_watch 156
#elif defined (__arm__)
-# define __NR_OABI_SYSCALL_BASE 0x900000
-# if defined(__thumb__) || defined(__ARM_EABI__)
-# define __NR_SYSCALL_BASE 0
-# else
-# define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE
-# endif
# define __NR_inotify_init (__NR_SYSCALL_BASE + 316)
# define __NR_inotify_add_watch (__NR_SYSCALL_BASE + 317)
# define __NR_inotify_rm_watch (__NR_SYSCALL_BASE + 318)
@@ -54,6 +49,10 @@
# define __NR_inotify_init 290
# define __NR_inotify_add_watch 291
# define __NR_inotify_rm_watch 292
+#elif defined (__m32r__)
+# define __NR_inotify_init 290
+# define __NR_inotify_add_watch 291
+# define __NR_inotify_rm_watch 292
#elif defined (__hppa__)
# define __NR_inotify_init 269
# define __NR_inotify_add_watch 270
@@ -76,23 +75,28 @@
# define __NR_inotify_add_watch (__NR_Linux + 248)
# define __NR_inotify_rm_watch (__NR_Linux + 249)
# endif
+#elif defined (__m68k__)
+# define __NR_inotify_init 284
+# define __NR_inotify_add_watch 285
+# define __NR_inotify_rm_watch 286
#else
# error "inotify not supported on this architecture!"
#endif
+#endif /* __NR_inotify_init */
-static inline int inotify_init (void)
+static inline int inotify_init(void)
{
- return syscall (__NR_inotify_init);
+ return syscall(__NR_inotify_init);
}
-static inline int inotify_add_watch (int fd, const char *name, __u32 mask)
+static inline int inotify_add_watch(int fd, const char *name, __u32 mask)
{
- return syscall (__NR_inotify_add_watch, fd, name, mask);
+ return syscall(__NR_inotify_add_watch, fd, name, mask);
}
-static inline int inotify_rm_watch (int fd, __u32 wd)
+static inline int inotify_rm_watch(int fd, __u32 wd)
{
- return syscall (__NR_inotify_rm_watch, fd, wd);
+ return syscall(__NR_inotify_rm_watch, fd, wd);
}
#endif /* _LINUX_INOTIFY_SYSCALLS_H */