From 9d114f58550b7fd582d1328e95592deca6012f95 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 23 May 2007 19:35:15 +0200 Subject: inotail.c: Coding style cleanups --- inotail.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/inotail.c b/inotail.c index 1081aec..4d44145 100644 --- a/inotail.c +++ b/inotail.c @@ -382,7 +382,9 @@ static int watch_files(struct file_struct *files, int n_files) /* 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) { + if (!files[i].ignore + && files[i].fd >= 0 + && files[i].i_watch == inev->wd) { f = &files[i]; break; } @@ -399,7 +401,6 @@ static int watch_files(struct file_struct *files, int n_files) } close(ifd); - return -1; } -- cgit v1.2.3-54-g00ecf From 701639c00d851f7f829ab6559e2fbd1d229ee298 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 29 May 2007 19:00:15 +0200 Subject: inotail.c: Fix handling of EINTR in watch_files() If inotail gets an EINTR signal while reading inotify events, it breaks. However, a common thing to generate these events is hitting ^Z/fg The patch fixes this shortcoming and allows inotail to be interrupted by EINTR. Patch from Anthony Martinez --- inotail.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/inotail.c b/inotail.c index 4d44145..e0ed410 100644 --- a/inotail.c +++ b/inotail.c @@ -368,10 +368,21 @@ static int watch_files(struct file_struct *files, int n_files) ssize_t len; int ev_idx = 0; - 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); + /* Keep trying in the case of EINTR (see below) */ + for (;;) { + len = read(ifd, buf, (n_files * INOTIFY_BUFLEN)); + if (unlikely(len < 0)) { + if (errno == EINTR) { + /* Some form of signal, likely ^Z/fg's STOP and CONT interrupted the inotify read, retry */ + continue; + } else { + fprintf(stderr, "Error: Could not read inotify events (%s)\n", strerror(errno)); + exit(EXIT_FAILURE); + } + } + + /* The read did succeed */ + break; } while (ev_idx < len) { -- cgit v1.2.3-54-g00ecf From 8da82b981b2c73c8e353f2d8054581d304adc3bf Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sat, 2 Jun 2007 16:06:20 +0200 Subject: inotail.c: Correct error condition in tail_pipe() write() returns 0 on end of file --- inotail.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inotail.c b/inotail.c index e0ed410..3a4bc1a 100644 --- a/inotail.c +++ b/inotail.c @@ -222,7 +222,7 @@ static ssize_t tail_pipe(struct file_struct *f) /* We will just tail everything here */ while ((rc = read(f->fd, buf, BUFFER_SIZE)) > 0) { - if (write(STDOUT_FILENO, buf, (size_t) rc) < 0) { + if (write(STDOUT_FILENO, buf, (size_t) rc) <= 0) { /* e.g. when writing to a pipe which gets closed */ fprintf(stderr, "Error: Could not write to stdout (%s)\n", strerror(errno)); return -1; -- cgit v1.2.3-54-g00ecf From 01f54bb5e9a1d6373a508859dcc809f5cdb5cd64 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 4 Jun 2007 14:32:20 +0200 Subject: inotail.c: Handle return value of lseek lseek() could fail so we better handle it. Based on a patch by Folkert van Heusden --- inotail.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/inotail.c b/inotail.c index 3a4bc1a..bb27702 100644 --- a/inotail.c +++ b/inotail.c @@ -132,7 +132,10 @@ static off_t lines_to_offset_from_end(struct file_struct *f, unsigned long n_lin /* Start of current block */ offset -= block_size; - lseek(f->fd, offset, SEEK_SET); + if (lseek(f->fd, offset, SEEK_SET) == (off_t) -1) { + fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno)); + return -1; + } rc = read(f->fd, buf, block_size); if (unlikely(rc < 0)) { @@ -166,7 +169,10 @@ static off_t lines_to_offset_from_begin(struct file_struct *f, unsigned long n_l int i; ssize_t rc, block_size = BUFFER_SIZE; - lseek(f->fd, offset, SEEK_SET); + if (lseek(f->fd, offset, SEEK_SET) == (off_t) -1) { + fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno)); + return -1; + } rc = read(f->fd, buf, block_size); if (unlikely(rc < 0)) { @@ -220,7 +226,7 @@ static ssize_t tail_pipe(struct file_struct *f) if (verbose) write_header(f->name); - /* We will just tail everything here */ + /* FIXME: We will just tail everything here for now */ while ((rc = read(f->fd, buf, BUFFER_SIZE)) > 0) { if (write(STDOUT_FILENO, buf, (size_t) rc) <= 0) { /* e.g. when writing to a pipe which gets closed */ @@ -282,7 +288,10 @@ static int tail_file(struct file_struct *f, unsigned long n_units, char mode, ch if (verbose) write_header(f->name); - lseek(f->fd, offset, SEEK_SET); + if (lseek(f->fd, offset, SEEK_SET) == (off_t) -1) { + fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno)); + return -1; + } while ((bytes_read = read(f->fd, buf, BUFFER_SIZE)) > 0) write(STDOUT_FILENO, buf, (size_t) bytes_read); @@ -309,7 +318,13 @@ static int handle_inotify_event(struct inotify_event *inev, struct file_struct * if (verbose) write_header(f->name); - lseek(f->fd, f->st_size, SEEK_SET); /* Old file size */ + /* Seek to old file size */ + if (lseek(f->fd, f->st_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; + } + while ((rc = read(f->fd, fbuf, BUFFER_SIZE)) != 0) write(STDOUT_FILENO, fbuf, (size_t) rc); -- cgit v1.2.3-54-g00ecf From 5015c1eb9a07b2f8351249eac62ab1fe55f03395 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 11 Jun 2007 17:46:50 +0200 Subject: inotail.c/.h: Implement is_digit to save some bytes of ctype.h inclusion --- inotail.c | 3 +-- inotail.h | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/inotail.c b/inotail.c index bb27702..075bb5d 100644 --- a/inotail.c +++ b/inotail.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -451,7 +450,7 @@ int main(int argc, char **argv) } else if (*optarg == '-') optarg++; - if (!isdigit(*optarg)) { + if (!is_digit(*optarg)) { fprintf(stderr, "Invalid number of lines: %s\n", optarg); exit(EXIT_FAILURE); } diff --git a/inotail.h b/inotail.h index 4c57867..836c1de 100644 --- a/inotail.h +++ b/inotail.h @@ -29,6 +29,8 @@ struct file_struct { #define IS_TAILABLE(mode) \ (S_ISREG(mode) || IS_PIPELIKE(mode) || S_ISCHR(mode)) +#define is_digit(c) ((c) >= '0' && (c) <= '9') + #ifdef DEBUG # define dprintf(fmt, args...) fprintf(stderr, fmt, ##args) #else -- cgit v1.2.3-54-g00ecf From 4b51d764955cf09604fffadad9b9b88c72ab45db Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 12 Jun 2007 18:05:22 +0200 Subject: inotail.c: Cleanup Save us some lines --- inotail.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/inotail.c b/inotail.c index 075bb5d..68f75c0 100644 --- a/inotail.c +++ b/inotail.c @@ -81,10 +81,9 @@ static void usage(const int status) static inline void setup_file(struct file_struct *f) { - f->fd = -1; + f->fd = f->i_watch = -1; f->st_size = 0; f->ignore = 0; - f->i_watch = -1; } static void ignore_file(struct file_struct *f) @@ -209,10 +208,8 @@ static off_t bytes_to_offset(struct file_struct *f, unsigned long 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; - } + } else if ((off_t) n_bytes < f->st_size) + offset = f->st_size - (off_t) n_bytes; return offset; } @@ -382,19 +379,18 @@ static int watch_files(struct file_struct *files, int n_files) ssize_t len; int ev_idx = 0; - /* Keep trying in the case of EINTR (see below) */ + /* Keep trying in the case of EINTR */ for (;;) { len = read(ifd, buf, (n_files * INOTIFY_BUFLEN)); if (unlikely(len < 0)) { - if (errno == EINTR) { - /* Some form of signal, likely ^Z/fg's STOP and CONT interrupted the inotify read, retry */ + /* Some form of signal, likely ^Z/fg's STOP and CONT interrupted the inotify read, retry */ + if (errno == EINTR) continue; - } else { + else { fprintf(stderr, "Error: Could not read inotify events (%s)\n", strerror(errno)); exit(EXIT_FAILURE); } } - /* The read did succeed */ break; } -- cgit v1.2.3-54-g00ecf From 347124f77d9502a21652bff4868f7c53052a8fca Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 12 Jun 2007 18:32:18 +0200 Subject: inotail.c: Also handle EAGAIN in watch_files() --- inotail.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inotail.c b/inotail.c index 68f75c0..2790005 100644 --- a/inotail.c +++ b/inotail.c @@ -379,12 +379,12 @@ static int watch_files(struct file_struct *files, int n_files) ssize_t len; int ev_idx = 0; - /* Keep trying in the case of EINTR */ + /* Keep trying in the case of EINTR or EAGAIN*/ for (;;) { len = read(ifd, buf, (n_files * INOTIFY_BUFLEN)); if (unlikely(len < 0)) { /* Some form of signal, likely ^Z/fg's STOP and CONT interrupted the inotify read, retry */ - if (errno == EINTR) + if (errno == EINTR || errno == EAGAIN) continue; else { fprintf(stderr, "Error: Could not read inotify events (%s)\n", strerror(errno)); -- cgit v1.2.3-54-g00ecf From d440e6dd7cb3db1f0c7b6723c098c5c31c530919 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 15 Jun 2007 11:35:42 +0200 Subject: inotail.c: Simplify EINTR handling in watch_files() We don't need another loop, just continue the surrounding while() on EINTR/EAGAIN --- inotail.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/inotail.c b/inotail.c index 2790005..967a0fa 100644 --- a/inotail.c +++ b/inotail.c @@ -379,20 +379,15 @@ static int watch_files(struct file_struct *files, int n_files) ssize_t len; int ev_idx = 0; - /* Keep trying in the case of EINTR or EAGAIN*/ - for (;;) { - len = read(ifd, buf, (n_files * INOTIFY_BUFLEN)); - if (unlikely(len < 0)) { - /* Some form of signal, likely ^Z/fg's STOP and CONT interrupted the inotify read, retry */ - if (errno == EINTR || errno == EAGAIN) - continue; - else { - fprintf(stderr, "Error: Could not read inotify events (%s)\n", strerror(errno)); - exit(EXIT_FAILURE); - } + len = read(ifd, buf, (n_files * INOTIFY_BUFLEN)); + if (unlikely(len < 0)) { + /* Some form of signal, likely ^Z/fg's STOP and CONT interrupted the inotify read, retry */ + if (errno == EINTR || errno == EAGAIN) + continue; /* Keep trying */ + else { + fprintf(stderr, "Error: Could not read inotify events (%s)\n", strerror(errno)); + exit(EXIT_FAILURE); } - /* The read did succeed */ - break; } while (ev_idx < len) { -- cgit v1.2.3-54-g00ecf From 06da83bc3a969c18ee99aa1b3ea511bf4c3763ff Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 15 Jun 2007 21:58:49 +0200 Subject: inotail.c: s/Inotify/inotify/ --- inotail.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inotail.c b/inotail.c index 967a0fa..aecbc1a 100644 --- a/inotail.c +++ b/inotail.c @@ -355,10 +355,10 @@ static int watch_files(struct file_struct *files, int n_files) ifd = inotify_init(); if (errno == ENOSYS) { - fprintf(stderr, "Error: Inotify is not supported by the kernel you're currently running.\n"); + 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)); + fprintf(stderr, "Error: Could not initialize inotify (%s)\n", strerror(errno)); exit(EXIT_FAILURE); } -- cgit v1.2.3-54-g00ecf