From a43df64eec6d02812b40d7e01edbeb47539866db Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 9 Aug 2009 22:06:56 +0200 Subject: [PATCH] tail: fix "tail +N file_shorter_than_N" Signed-off-by: Denys Vlasenko --- coreutils/tail.c | 16 ++++++++++------ testsuite/tail.tests | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) create mode 100755 testsuite/tail.tests diff --git a/coreutils/tail.c b/coreutils/tail.c index ef1326c83..5f98bff82 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c @@ -50,12 +50,12 @@ static ssize_t tail_read(int fd, char *buf, size_t count) off_t current; struct stat sbuf; - /* (A good comment is missing here) */ - current = lseek(fd, 0, SEEK_CUR); /* /proc files report zero st_size, don't lseek them. */ - if (fstat(fd, &sbuf) == 0 && sbuf.st_size) + if (fstat(fd, &sbuf) == 0 && sbuf.st_size) { + current = lseek(fd, 0, SEEK_CUR); if (sbuf.st_size < current) lseek(fd, 0, SEEK_SET); + } r = full_read(fd, buf, count); if (r < 0) { @@ -119,10 +119,11 @@ int tail_main(int argc, char **argv) #if ENABLE_FEATURE_FANCY_TAIL /* q: make it impossible for nfiles to be > header_threshhold */ if (opt & 0x8) header_threshhold = UINT_MAX; // -q + //if (opt & 0x10) // -s if (opt & 0x20) header_threshhold = 0; // -v -#define FOLLOW_RETRY (opt & 0x40) +# define FOLLOW_RETRY (opt & 0x40) #else -#define FOLLOW_RETRY 0 +# define FOLLOW_RETRY 0 #endif argc -= optind; argv += optind; @@ -189,7 +190,7 @@ int tail_main(int argc, char **argv) off_t current = lseek(fds[i], 0, SEEK_END); if (current > 0) { if (count == 0) - continue; /* showing zero lines is easy :) */ + continue; /* showing zero bytes is easy :) */ current -= count; if (current < 0) current = 0; @@ -201,12 +202,15 @@ int tail_main(int argc, char **argv) buf = tailbuf; taillen = 0; + /* "We saw 1st line/byte". + * Used only by +N code ("start from Nth", 1-based) */ seen = 1; newlines_seen = 0; while ((nread = tail_read(fds[i], buf, tailbufsize-taillen)) > 0) { if (from_top) { int nwrite = nread; if (seen < count) { + /* We need to skip a few more bytes/lines */ if (COUNT_BYTES) { nwrite -= (count - seen); seen = count; diff --git a/testsuite/tail.tests b/testsuite/tail.tests new file mode 100755 index 000000000..d97bf7bbe --- /dev/null +++ b/testsuite/tail.tests @@ -0,0 +1,17 @@ +#!/bin/sh + +# Copyright 2009 by Denys Vlasenko +# Licensed under GPL v2, see file LICENSE for details. + +. testing.sh + +# testing "test name" "command" "expected result" "file input" "stdin" +# file input will be file called "input" +# test can create a file "actual" instead of writing to stdout + +testing "tail: +N with N > file length" \ + "tail -c +55 2>&1; echo \$?" \ + "0\n" \ + "" "qw" + +exit $FAILCOUNT -- 2.25.1