summaryrefslogtreecommitdiff
path: root/inotail.c
diff options
context:
space:
mode:
Diffstat (limited to 'inotail.c')
-rw-r--r--inotail.c68
1 files changed, 37 insertions, 31 deletions
diff --git a/inotail.c b/inotail.c
index 8a9e1a9..7b58477 100644
--- a/inotail.c
+++ b/inotail.c
@@ -99,21 +99,23 @@ static void write_header(char *filename)
first_file = 0;
}
-static off_t lines_to_offset_from_begin(struct file_struct *f, unsigned int n_lines)
+static off_t lines_to_offset_from_end(struct file_struct *f, unsigned int n_lines)
{
char buf[BUFFER_SIZE];
- off_t offset = 0;
-
- /* tail everything for 'inotail -n +0' */
- if (n_lines == 0)
- return 0;
+ off_t offset = f->st_size;
- n_lines--;
+ n_lines++; /* We also count the last \n */
memset(&buf, 0, sizeof(buf));
- while (offset <= f->st_size && n_lines > 0) {
+ while (offset > 0 && n_lines > 0) {
int i, rc;
- int block_size = BUFFER_SIZE;
+ int block_size = BUFFER_SIZE; /* Size of the current block we're reading */
+
+ if (offset < BUFFER_SIZE)
+ block_size = offset;
+
+ /* Start of current block */
+ offset -= block_size;
lseek(f->fd, offset, SEEK_SET);
@@ -123,42 +125,37 @@ static off_t lines_to_offset_from_begin(struct file_struct *f, unsigned int n_li
return -1;
}
- for (i = 0; i < block_size; i++) {
+ for (i = block_size; i > 0; i--) {
if (buf[i] == '\n') {
n_lines--;
+
if (n_lines == 0) {
- offset += i + 1;
- return offset;
+ offset += i + 1; /* We don't want the first \n */
+ break;
}
}
}
-
- offset += block_size;
}
return offset;
+
}
-static off_t lines_to_offset(struct file_struct *f, unsigned int n_lines)
+static off_t lines_to_offset_from_begin(struct file_struct *f, unsigned int n_lines)
{
char buf[BUFFER_SIZE];
- off_t offset = f->st_size;
+ off_t offset = 0;
- if (from_begin)
- return lines_to_offset_from_begin(f, n_lines);
+ /* tail everything for 'inotail -n +0' */
+ if (n_lines == 0)
+ return 0;
- n_lines++; /* We also count the last \n */
+ n_lines--;
memset(&buf, 0, sizeof(buf));
- while (offset > 0 && n_lines > 0) {
+ while (offset <= f->st_size && n_lines > 0) {
int i, rc;
- int block_size = BUFFER_SIZE; /* Size of the current block we're reading */
-
- if (offset < BUFFER_SIZE)
- block_size = offset;
-
- /* Start of current block */
- offset -= block_size;
+ int block_size = BUFFER_SIZE;
lseek(f->fd, offset, SEEK_SET);
@@ -168,21 +165,30 @@ static off_t lines_to_offset(struct file_struct *f, unsigned int n_lines)
return -1;
}
- for (i = block_size; i > 0; i--) {
+ for (i = 0; i < block_size; i++) {
if (buf[i] == '\n') {
n_lines--;
-
if (n_lines == 0) {
- offset += i + 1; /* We don't want the first \n */
- break;
+ offset += i + 1;
+ return offset;
}
}
}
+
+ offset += block_size;
}
return offset;
}
+static off_t lines_to_offset(struct file_struct *f, unsigned int n_lines)
+{
+ if (from_begin)
+ return lines_to_offset_from_begin(f, n_lines);
+ else
+ return lines_to_offset_from_end(f, n_lines);
+}
+
static inline off_t bytes_to_offset(struct file_struct *f, unsigned int n_bytes)
{
/* tail everything for 'inotail -c +0' */