summaryrefslogtreecommitdiffstats
path: root/contrib/dialog/tailbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/dialog/tailbox.c')
-rw-r--r--contrib/dialog/tailbox.c57
1 files changed, 43 insertions, 14 deletions
diff --git a/contrib/dialog/tailbox.c b/contrib/dialog/tailbox.c
index 51db836..3499b4b 100644
--- a/contrib/dialog/tailbox.c
+++ b/contrib/dialog/tailbox.c
@@ -1,9 +1,9 @@
/*
- * $Id: tailbox.c,v 1.56 2010/04/28 20:52:20 tom Exp $
+ * $Id: tailbox.c,v 1.61 2011/01/16 21:48:16 tom Exp $
*
- * tailbox.c -- implements the tail box
+ * tailbox.c -- implements the tail box
*
- * Copyright 2000-2009,2010 Thomas E. Dickey
+ * Copyright 2000-2010,2011 Thomas E. Dickey
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License, version 2.1
@@ -26,6 +26,7 @@
#include <dialog.h>
#include <dlg_keys.h>
+#include <sys/stat.h>
typedef struct {
DIALOG_CALLBACK obj;
@@ -34,6 +35,7 @@ typedef struct {
int hscroll;
int old_hscroll;
char line[MAX_LEN + 1];
+ off_t last_pos;
} MY_OBJ;
/*
@@ -106,14 +108,15 @@ static void
last_lines(MY_OBJ * obj, int target)
{
FILE *fp = obj->obj.input;
- long inx;
+ size_t inx;
int count = 0;
char buf[BUFSIZ + 1];
- long size_to_read;
+ size_t size_to_read;
+ size_t size_as_read;
long offset = 0;
long fpos = 0;
- if (fseek(fp, 0, SEEK_END) == -1
+ if (fseek(fp, 0L, SEEK_END) == -1
|| (fpos = ftell(fp)) < 0)
dlg_exiterr("Error moving file pointer in last_lines().");
@@ -123,21 +126,27 @@ last_lines(MY_OBJ * obj, int target)
if (fpos >= BUFSIZ) {
size_to_read = BUFSIZ;
} else {
- size_to_read = fpos;
+ size_to_read = (size_t) fpos;
}
- fpos = fpos - size_to_read;
+ fpos = fpos - (long) size_to_read;
if (fseek(fp, fpos, SEEK_SET) == -1)
dlg_exiterr("Error moving file pointer in last_lines().");
- (void) fread(buf, (size_t) size_to_read, 1, fp);
+ size_as_read = fread(buf, sizeof(char), size_to_read, fp);
if (ferror(fp))
dlg_exiterr("Error reading file in last_lines().");
- offset += size_to_read;
- for (inx = size_to_read - 1; inx >= 0; --inx) {
+ if (size_as_read == 0) {
+ fpos = 0;
+ offset = 0;
+ break;
+ }
+
+ offset += (long) size_as_read;
+ for (inx = size_as_read - 1; inx != 0; --inx) {
if (buf[inx] == '\n') {
if (++count > target)
break;
- offset = inx + 1;
+ offset = (long) (inx + 1);
}
}
@@ -181,16 +190,35 @@ print_last_page(MY_OBJ * obj)
static void
repaint_text(MY_OBJ * obj)
{
+ FILE *fp = obj->obj.input;
int cur_y, cur_x;
getyx(obj->obj.win, cur_y, cur_x);
obj->old_hscroll = obj->hscroll;
+
print_last_page(obj);
+ obj->last_pos = ftell(fp);
+
(void) wmove(obj->obj.win, cur_y, cur_x); /* Restore cursor position */
wrefresh(obj->obj.win);
}
static bool
+handle_input(DIALOG_CALLBACK * cb)
+{
+ MY_OBJ *obj = (MY_OBJ *) cb;
+ FILE *fp = obj->obj.input;
+ struct stat sb;
+
+ if (fstat(fileno(fp), &sb) == 0
+ && sb.st_size != obj->last_pos) {
+ repaint_text(obj);
+ }
+
+ return TRUE;
+}
+
+static bool
handle_my_getc(DIALOG_CALLBACK * cb, int ch, int fkey, int *result)
{
MY_OBJ *obj = (MY_OBJ *) cb;
@@ -231,8 +259,8 @@ handle_my_getc(DIALOG_CALLBACK * cb, int ch, int fkey, int *result)
clearerr(cb->input);
ch = getc(cb->input);
(void) ungetc(ch, cb->input);
- if ((ch != EOF) || (obj->hscroll != obj->old_hscroll)) {
- repaint_text(obj);
+ if (ch != EOF) {
+ handle_input(cb);
}
break;
case ESC:
@@ -327,6 +355,7 @@ dialog_tailbox(const char *title, const char *file, int height, int width, int b
obj->obj.input = fd;
obj->obj.win = dialog;
obj->obj.handle_getc = handle_my_getc;
+ obj->obj.handle_input = bg_task ? handle_input : 0;
obj->obj.keep_bg = bg_task && dialog_vars.cant_kill;
obj->obj.bg_task = bg_task;
obj->text = text;
OpenPOWER on IntegriCloud