From 05d1bec3e5a34449ffde7f71648084069b1319f5 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Thu, 9 Feb 1995 17:05:43 +0000 Subject: (wc): Don't overcount the number of bytes when reading from a regular file on stdin with file pointer not at BOF. From Karl Heuer. --- src/wc.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/wc.c') diff --git a/src/wc.c b/src/wc.c index 7086c96c0..34706ae67 100644 --- a/src/wc.c +++ b/src/wc.c @@ -201,19 +201,29 @@ wc (fd, file) register int bytes_read; register int in_word = 0; register unsigned long lines, words, chars; - struct stat stats; lines = words = chars = 0; /* When counting only bytes, save some line- and word-counting - overhead. If FD is a `regular' Unix file, using fstat is enough + overhead. If FD is a `regular' Unix file, using lseek is enough to get its size in bytes. Otherwise, read blocks of BUFFER_SIZE - bytes at a time until EOF. */ + bytes at a time until EOF. + + NOTE: using fstat and stats.st_size (and omitting the lseek calls) + over counts when the file is not positioned at the beginning. + For example the command `(dd skip=9999; wc -c) < /etc/group' + should make wc report `0' bytes. */ + if (print_chars && !print_words && !print_lines) { - if (fstat (fd, &stats) == 0 && S_ISREG (stats.st_mode)) + struct stat stats; + off_t current_pos, end_pos; + + if (fstat (fd, &stats) == 0 && S_ISREG (stats.st_mode) + && (current_pos = lseek (fd, (off_t)0, SEEK_CUR)) != -1 + && (end_pos = lseek (fd, (off_t)0, SEEK_END)) != -1) { - chars = stats.st_size; + chars = end_pos - current_pos; } else { -- cgit v1.2.3-54-g00ecf