From 62e7af0326786a7dec91d982238948eddab9d6af Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 12 Feb 2016 10:16:11 -0800 Subject: split: fix problems with /dev/zero Problem reported by Nelson H.F. Beebe in: http://bugs.gnu.org/22624 Other problems also fixed: basically, the code got confused because GNU/Linux reports that /dev/zero has size zero. * src/split.c (input_file_size): Now takes struct stat *, not just size. Always store the first buffer. All callers changed. Treat /dev/zero as an infinitely-large file, both on GNU/Linux where fstat and lseek say its size is zero, and on GNU/Hurd where they say the size is OFF_T_MAX. (cwrite): Return true on success. (bytes_split): Don't try to read past EOF, and stop if a write fails. (lines_rr): Omit stray check for ignorable errno. (main): Get file size only when n_units > 1, since that's the only time it is needed. Defer most of the work to input_file_size. * tests/split/l-chunk.sh: Adjust tests to match new behavior on oddball inputs. --- tests/split/l-chunk.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/split/l-chunk.sh b/tests/split/l-chunk.sh index dac98d05e..38297dea1 100755 --- a/tests/split/l-chunk.sh +++ b/tests/split/l-chunk.sh @@ -24,9 +24,9 @@ echo "split: invalid number of chunks: '1o'" > exp split -n l/1o 2>err && fail=1 compare exp err || fail=1 -echo "split: -: cannot determine file size" > exp -echo | split -n l/1 2>err && fail=1 -compare exp err || fail=1 +echo > exp +echo | split -n l/1 || fail=1 +compare exp xaa || fail=1 # N can be greater than the file size # in which case no data is extracted, or empty files are written @@ -34,14 +34,14 @@ split -n l/10 /dev/null || fail=1 test "$(stat -c %s x* | uniq -c | sed 's/^ *//; s/ /x/')" = "10x0" || fail=1 rm x?? -# Ensure the correct number of files written -# even if there is more data than the reported file size -split -n l/2 /dev/zero -test "$(stat -c %s x* | wc -l)" = '2' || fail=1 +# 'split' should reject any attempt to create an infinitely +# long output file. +returns_ 1 split -n l/2 /dev/zero || fail=1 rm x?? # Repeat the above, but with 1/2, not l/2: -split -n 1/2 /dev/zero || fail=1 +returns_ 1 split -n 1/2 /dev/zero || fail=1 +rm x?? # Ensure --elide-empty-files is honored split -e -n l/10 /dev/null || fail=1 @@ -54,7 +54,7 @@ lines=\ printf "%s" "$lines" | tr '~' '\n' > in || framework_failure_ echo "split: invalid chunk number: '16'" > exp -split -n l/16/15 in 2>err.t && fail=1 +returns_ 1 split -n l/16/15 in 2>err.t || fail=1 sed "s/': .*/'/" < err.t > err || framework_failure_ compare exp err || fail=1 -- cgit v1.2.3-70-g09d2