From 931e0f2a708965001857d60cedf1b1940389cbe6 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 5 Jan 2012 09:26:32 +0100 Subject: [PATCH] split: avoid failure due to leftover 'errno' value * src/split.c (lines_chunk_split): Fix logic bug that led to unwarranted failure of "split -n l/2 /dev/zero" on NetBSD 5.1. The same would happen when splitting a growing file, where open/lseek-end gives one size, but by the time we read, there is more data available. (bytes_chunk_extract): Likewise. * NEWS (Bug fixes): Mention this. * tests/split/l-chunk: The latter case was not exercised. Add code to do that. Bug introduced with the chunk-selecting feature in v8.7-25-gbe10739. Co-authored-by: Jim Meyering --- NEWS | 6 ++++++ src/split.c | 4 ++-- tests/split/l-chunk | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index ed6f83154..ceca0568b 100644 --- a/NEWS +++ b/NEWS @@ -29,6 +29,12 @@ GNU coreutils NEWS -*- outline -*- and NcFsd file systems. This did not affect Unix/Linux-based kernels. [bug introduced in coreutils-8.0, when rm began using fts] + split -n 1/2 FILE no longer fails when operating on a growing file, or + (on some systems) when operating on a non-regular file like /dev/zero. + It would report "/dev/zero: No such file or directory" even though + the file obviously exists. Same for -n l/2. + [bug introduced in coreutils-8.8, with the addition of the -n option] + stat -f now recognizes the FhGFS and PipeFS file system types. tac no longer fails to handle two or more non-seekable inputs diff --git a/src/split.c b/src/split.c index 5b00fe804..2eb343b15 100644 --- a/src/split.c +++ b/src/split.c @@ -623,11 +623,11 @@ lines_chunk_split (uintmax_t k, uintmax_t n, char *buf, size_t bufsize, { char *bp = buf, *eob; size_t n_read = full_read (STDIN_FILENO, buf, bufsize); - n_read = MIN (n_read, file_size - n_written); if (n_read < bufsize && errno) error (EXIT_FAILURE, errno, "%s", infile); else if (n_read == 0) break; /* eof. */ + n_read = MIN (n_read, file_size - n_written); chunk_truncated = false; eob = buf + n_read; @@ -718,11 +718,11 @@ bytes_chunk_extract (uintmax_t k, uintmax_t n, char *buf, size_t bufsize, while (start < end) { size_t n_read = full_read (STDIN_FILENO, buf, bufsize); - n_read = MIN (n_read, end - start); if (n_read < bufsize && errno) error (EXIT_FAILURE, errno, "%s", infile); else if (n_read == 0) break; /* eof. */ + n_read = MIN (n_read, end - start); if (full_write (STDOUT_FILENO, buf, n_read) != n_read && ! ignorable (errno)) error (EXIT_FAILURE, errno, "%s", quote ("-")); diff --git a/tests/split/l-chunk b/tests/split/l-chunk index dd92b7002..c4e696815 100755 --- a/tests/split/l-chunk +++ b/tests/split/l-chunk @@ -40,6 +40,9 @@ split -n l/2 /dev/zero test "$(stat -c %s x* | wc -l)" = '2' || fail=1 rm x?? +# Repeat the above, but with 1/2, not l/2: +split -n 1/2 /dev/zero || fail=1 + # Ensure --elide-empty-files is honored split -e -n l/10 /dev/null || fail=1 stat x?? 2>/dev/null && fail=1 -- 2.11.4.GIT