summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2011-05-20 01:26:41 +0100
committerPádraig Brady <P@draigBrady.com>2011-05-26 00:12:05 +0100
commit6eec064597c2f440c51146cac85dc2326a0e0cda (patch)
tree936a674ace7b410ae287fa8bb709b46ca39b539f
parent5908e29e825286121c69f5c10c313ccae6860fa7 (diff)
downloadcoreutils-6eec064597c2f440c51146cac85dc2326a0e0cda.tar.xz
split: exit when we can no longer write to a --filter
* src/split.c (bytes_split): Stop reading when we can no longer write to a child process. (lines_rr): Likewise. (lines_bytes_split): No change is made here since input is bounded by the original file size. * test/split/filter: Add test cases.
-rw-r--r--src/split.c15
-rwxr-xr-xtests/split/filter4
2 files changed, 19 insertions, 0 deletions
diff --git a/src/split.c b/src/split.c
index 3f925380e..5e203f1b7 100644
--- a/src/split.c
+++ b/src/split.c
@@ -462,6 +462,12 @@ bytes_split (uintmax_t n_bytes, char *buf, size_t bufsize, uintmax_t max_files)
cwrite (new_file_flag, bp_out, w);
opened += new_file_flag;
new_file_flag = !max_files || (opened < max_files);
+ if (!new_file_flag && ignorable (errno))
+ {
+ /* If filter no longer accepting input, stop reading. */
+ n_read = 0;
+ break;
+ }
bp_out += w;
to_read -= w;
to_write = n_bytes;
@@ -817,6 +823,7 @@ static void
lines_rr (uintmax_t k, uintmax_t n, char *buf, size_t bufsize)
{
bool wrapped = false;
+ bool wrote = false;
bool file_limit;
size_t i_file;
of_t *files IF_LINT (= NULL);
@@ -903,6 +910,9 @@ lines_rr (uintmax_t k, uintmax_t n, char *buf, size_t bufsize)
else if (fwrite (bp, to_write, 1, files[i_file].ofile) != 1
&& ! ignorable (errno))
error (EXIT_FAILURE, errno, "%s", files[i_file].of_name);
+ if (! ignorable (errno))
+ wrote = true;
+
if (file_limit)
{
if (fclose (files[i_file].ofile) != 0 && ! ignorable (errno))
@@ -913,6 +923,10 @@ lines_rr (uintmax_t k, uintmax_t n, char *buf, size_t bufsize)
if (next && ++i_file == n)
{
wrapped = true;
+ /* If no filters are accepting input, stop reading. */
+ if (! wrote)
+ goto no_filters;
+ wrote = false;
i_file = 0;
}
}
@@ -921,6 +935,7 @@ lines_rr (uintmax_t k, uintmax_t n, char *buf, size_t bufsize)
}
}
+no_filters:
/* Ensure all files created, so that any existing files are truncated,
and to signal any waiting fifo consumers.
Also, close any open file descriptors.
diff --git a/tests/split/filter b/tests/split/filter
index 0614841ed..a42c5539e 100755
--- a/tests/split/filter
+++ b/tests/split/filter
@@ -47,4 +47,8 @@ stat x?? 2>/dev/null && fail=1
# where they would result in a non zero exit from split.
yes | head -n200K | split -b1G --filter='head -c1 >/dev/null' || fail=1
+# Ensure that endless input is ignored when all filters finish
+timeout 10 yes | split --filter="head -c1 >/dev/null" -n r/1 || fail=1
+timeout 10 split --filter="head -c1 >/dev/null" -n 1 /dev/zero || fail=1
+
Exit $fail