diff options
author | Pádraig Brady <P@draigBrady.com> | 2011-05-20 01:26:41 +0100 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2011-05-26 00:12:05 +0100 |
commit | 6eec064597c2f440c51146cac85dc2326a0e0cda (patch) | |
tree | 936a674ace7b410ae287fa8bb709b46ca39b539f | |
parent | 5908e29e825286121c69f5c10c313ccae6860fa7 (diff) | |
download | coreutils-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.c | 15 | ||||
-rwxr-xr-x | tests/split/filter | 4 |
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 |