mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2026-10-24 02:08:57 +03:00
wc: fix buffer boundary calculations
Problem reported by Scott Orme (Bug#82013). * src/wc.c (wc): Fix calculations of file sizes vs page size vs block size.
This commit is contained in:
4
NEWS
4
NEWS
@@ -33,6 +33,10 @@ GNU coreutils NEWS -*- outline -*-
|
||||
in GB18030 locales, and word counts in UTF-8 locales.
|
||||
[bug introduced in coreutils-9.5]
|
||||
|
||||
'wc -c' no longer miscounts bytes when stdin has a nonzero offset
|
||||
into a seekable file whose size is a multiple of the page size.
|
||||
[bug introduced in coreutils-8.24]
|
||||
|
||||
** New Features
|
||||
|
||||
'env' and 'printenv' now support the --quoting-style option
|
||||
|
||||
@@ -577,6 +577,7 @@ Santiago Vila Doncel sanvila@unex.es
|
||||
Savochkin Andrey Vladimirovich saw@msu.ru
|
||||
Scott Harrison scott.gnu.2009@scottrix.co.uk
|
||||
Scott Lurndal slurn@griffin.engr.sgi.com
|
||||
Scott Orme scott.orme@gmail.com
|
||||
Sébastien Maret smaret@umich.edu
|
||||
Sergei Steshenko sergstesh@yahoo.com
|
||||
Sergey Vlasov vsu@altlinux.org
|
||||
|
||||
27
src/wc.c
27
src/wc.c
@@ -428,7 +428,7 @@ wc (int fd, char const *file_x, struct fstatus *fstatus)
|
||||
;
|
||||
else if (end_pos % page_size)
|
||||
{
|
||||
/* We only need special handling of /proc and /sys files etc.
|
||||
/* We need special handling of /proc and /sys files etc. only
|
||||
when they're a multiple of PAGE_SIZE. In the common case
|
||||
for files with st_size not a multiple of PAGE_SIZE,
|
||||
it's more efficient and accurate to use st_size.
|
||||
@@ -436,20 +436,25 @@ wc (int fd, char const *file_x, struct fstatus *fstatus)
|
||||
Be careful here. The current position may actually be
|
||||
beyond the end of the file. As in the example above. */
|
||||
|
||||
bytes = end_pos < current_pos ? 0 : end_pos - current_pos;
|
||||
if (bytes && 0 <= lseek (fd, bytes, SEEK_CUR))
|
||||
skip_read = true;
|
||||
else
|
||||
bytes = 0;
|
||||
if (current_pos < end_pos)
|
||||
{
|
||||
bytes = end_pos - current_pos;
|
||||
skip_read = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (0 < end_pos)
|
||||
{
|
||||
off_t hi_pos = (end_pos
|
||||
- end_pos % (STP_BLKSIZE (&fstatus->st) + 1));
|
||||
if (0 <= current_pos && current_pos < hi_pos
|
||||
&& 0 <= lseek (fd, hi_pos, SEEK_CUR))
|
||||
off_t ep_1 = end_pos - 1;
|
||||
off_t hi_pos = ep_1 - ep_1 % STP_BLKSIZE (&fstatus->st);
|
||||
if (current_pos < hi_pos)
|
||||
bytes = hi_pos - current_pos;
|
||||
}
|
||||
|
||||
if (0 < bytes && lseek (fd, bytes, SEEK_CUR) < 0)
|
||||
{
|
||||
bytes = 0;
|
||||
skip_read = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (! skip_read)
|
||||
|
||||
Reference in New Issue
Block a user