]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
split: avoid failure due to leftover 'errno' value
authorBruno Haible <bruno@clisp.org>
Thu, 5 Jan 2012 08:26:32 +0000 (09:26 +0100)
committerJim Meyering <meyering@redhat.com>
Thu, 5 Jan 2012 10:46:48 +0000 (11:46 +0100)
* 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 <meyering@redhat.com>
NEWS
src/split.c
tests/split/l-chunk

diff --git a/NEWS b/NEWS
index ed6f83154f50e0e1fac5f8f3a34c5f345c517d11..ceca0568b9c7e4c51ed8305630993bfe38d53a90 100644 (file)
--- 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
index 5b00fe8046677c9b41b4201b988a4260d61fec12..2eb343b15cfebf3948e3d68bb509efd7a46ba961 100644 (file)
@@ -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 ("-"));
index dd92b7002bf7b3639c44a9d315451599d5e6ab51..c4e696815f6203fdea8482f07a6ad8e9d8a90f90 100755 (executable)
@@ -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