From f91f2bf951de16553ffdf88c116e722809341b5c Mon Sep 17 00:00:00 2001 From: Pádraig Brady Date: Fri, 12 Feb 2016 20:15:51 -0800 Subject: split: adjust recent --number changes * src/split.c (lines_rr): Reinstate the conditional setting of the WROTE boolean, as otherwise split -n r/1 would consume all input when all --filter commands are stopped. There was a test in place to check for this, but it was incorrect as detailed below. (input_file_size): Immediately disallow --number with non seekable inputs, as such an invocation is not currently generally supported and will fail as the data overflows the internal buffer. * tests/split/l-chunk.sh: Adjust to again disallow -n /dev/zero. Also change all '&& fail=1' checks to use the 'returns_ 1' form. * tests/split/filter.sh: Change the no longer supported /dev/zero case to a regular $OFF_T_MAX file (supported on XFS for example). Also fix the timeout(1) commands so they're not subject to pipefail issues. --- src/split.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/split.c b/src/split.c index 0b10600cd..676aa2e02 100644 --- a/src/split.c +++ b/src/split.c @@ -278,6 +278,14 @@ CHUNKS may be:\n\ static off_t input_file_size (int fd, struct stat const *st, char *buf, size_t bufsize) { + off_t cur = lseek (fd, 0, SEEK_CUR); + if (cur < 0) + { + if (errno == ESPIPE) + errno = 0; /* Suppress confusing seek error. */ + return -1; + } + off_t size = 0; do { @@ -290,19 +298,20 @@ input_file_size (int fd, struct stat const *st, char *buf, size_t bufsize) } while (size < bufsize); - /* The file contains at least BUFSIZE bytes. Infer its size via - st->st_size if this seems reliable, or via lseek if not. */ - off_t cur = lseek (fd, 0, SEEK_CUR); - off_t end; - if (cur < 0) - return -1; - if (cur < size) + /* Note we check st_size _after_ the read() above + because /proc files on GNU/Linux are seekable + but have st_size == 0. */ + if (st->st_size == 0) { - /* E.g., /dev/zero on GNU/Linux, where CUR is zero and SIZE == BUFSIZE. - Assume there is no limit to the file size. */ + /* We've filled the buffer, from a seekable file, + which has an st_size==0, E.g., /dev/zero on GNU/Linux. + Assume there is no limit to file size. */ errno = EOVERFLOW; return -1; } + + cur += size; + off_t end; if (usable_st_size (st) && cur <= st->st_size) end = st->st_size; else @@ -1197,7 +1206,8 @@ lines_rr (uintmax_t k, uintmax_t n, char *buf, size_t bufsize) quotef (files[i_file].of_name)); } - wrote = true; + if (! ignorable (errno)) + wrote = true; if (file_limit) { @@ -1558,8 +1568,7 @@ main (int argc, char **argv) char *buf = ptr_align (b, page_size); size_t initial_read = SIZE_MAX; - if ((split_type == type_chunk_bytes || split_type == type_chunk_lines) - && n_units != 1) + if (split_type == type_chunk_bytes || split_type == type_chunk_lines) { file_size = input_file_size (STDIN_FILENO, &in_stat_buf, buf, in_blk_size); -- cgit v1.2.3-54-g00ecf