From 6eec064597c2f440c51146cac85dc2326a0e0cda Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?=
Date: Fri, 20 May 2011 01:26:41 +0100 Subject: [PATCH] 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. --- src/split.c | 15 +++++++++++++++ tests/split/filter | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/src/split.c b/src/split.c index 3f92538..5e203f1 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 0614841..a42c553 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 -- 2.7.4