>From 72278d165dd968a4bf5192cfa38603472755016a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]>
Date: Tue, 24 May 2011 09:59:08 +0100
Subject: [PATCH] split: fix cases where -n l/... creates extraneous files
* src/split.c (lines_chunk_split): Ensure that data is only
written to stdout when k specified. Also ensure that
extra files are not created when there is more data available
than reported in the file size.
* tests/misc/split-lchunk: Verify that split -n l/k/n doesn't
generate any files, and that -n l/n always generates n files.
* NEWS: Mention the fix.
---
NEWS | 3 +++
src/split.c | 17 ++++++++++++++---
tests/misc/split-lchunk | 16 ++++++++++++++++
3 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/NEWS b/NEWS
index a71f832..502a5c6 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,9 @@ GNU coreutils NEWS -*- outline -*-
printf '%d' '"' no longer accesses out-of-bounds memory in the diagnostic.
[bug introduced in sh-utils-1.16]
+ split --number l/... no longer creates extraneous files in certain cases.
+ [bug introduced in coreutils-8.8]
+
** New features
split accepts a new --filter=CMD option. With it, split filters output
diff --git a/src/split.c b/src/split.c
index 0e13b5b..58d28db 100644
--- a/src/split.c
+++ b/src/split.c
@@ -651,7 +651,7 @@ lines_chunk_split (uintmax_t k, uintmax_t n, char *buf, size_t bufsize,
&& ! ignorable (errno))
error (EXIT_FAILURE, errno, "%s", _("write error"));
}
- else
+ else if (! k)
cwrite (new_file_flag, bp, to_write);
n_written += to_write;
bp += to_write;
@@ -663,7 +663,15 @@ lines_chunk_split (uintmax_t k, uintmax_t n, char *buf, size_t bufsize,
while (next || chunk_end <= n_written - 1)
{
if (!next && bp == eob)
- break; /* replenish buf, before going to next chunk. */
+ {
+ /* replenish buf, before going to next chunk. */
+
+ /* If we're going to stop reading,
+ then count the current chunk. */
+ if (n_written >= file_size)
+ chunk_no++;
+ break;
+ }
chunk_no++;
if (k && chunk_no > k)
return;
@@ -672,7 +680,10 @@ lines_chunk_split (uintmax_t k, uintmax_t n, char *buf, size_t bufsize,
else
chunk_end += chunk_size;
if (chunk_end <= n_written - 1)
- cwrite (true, NULL, 0);
+ {
+ if (! k)
+ cwrite (true, NULL, 0);
+ }
else
next = false;
}
diff --git a/tests/misc/split-lchunk b/tests/misc/split-lchunk
index 0f1693b..762138b 100755
--- a/tests/misc/split-lchunk
+++ b/tests/misc/split-lchunk
@@ -34,6 +34,12 @@ 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
+rm x??
+
# Ensure --elide-empty-files is honored
split -e -n l/10 /dev/null || fail=1
stat x?? 2>/dev/null && fail=1
@@ -66,9 +72,19 @@ for ELIDE_EMPTY in '' '-e'; do
test "$DEBUGGING" && printf "\n---io-blk-size=$IO_BLKSIZE $ELIDE_EMPTY\n"
for N in 6 8 12 15 22; do
rm -f x*
+
+ if test -z "$ELIDE_EMPTY"; then
+ split ---io-blksize=$IO_BLKSIZE $ELIDE_EMPTY -n l/2/$N in > chunk.k
+ stat x* >/dev/null 2>/dev/null && fail=1
+ fi
+
split ---io-blksize=$IO_BLKSIZE $ELIDE_EMPTY -n l/$N in
echo $(stat -c "%02s" x*) >> out
+ if test -z "$ELIDE_EMPTY"; then
+ compare chunk.k xab || fail=1
+ fi
+
if test "$DEBUGGING"; then
# Output partition pattern
size=$(printf "%s" "$lines" | wc -c)
--
1.7.5.1