I notice that split --filter spuriously returned with status 141 just because the filter finished early. This is a fairly good way to reproduce:
yes | head -n200K | split -b1G --filter='head -c1 >/dev/null' I avoided this by not unblocking SIGPIPEs before calling closeout(), which just lets any pending SIGPIPEs through. I can't see why we would need to unblock them. cheers, Pádraig.
>From 4a497001757191a38a27dd8b8e28ecbc78869b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]> Date: Thu, 19 May 2011 23:23:23 +0100 Subject: [PATCH] split: return success even if a --filter exits src/split.c (main): Don't unblock SIGPIPE before cleanup, as then any pending signals will be sent and cause the main split process to exit with a non zero status (141). * test/split/filter: Add a test for this case. --- src/split.c | 6 ++---- tests/split/filter | 4 ++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/split.c b/src/split.c index 05315e6..ccd91fd 100644 --- a/src/split.c +++ b/src/split.c @@ -1218,15 +1218,15 @@ main (int argc, char **argv) /* When filtering, closure of one pipe must not terminate the process, as there may still be other streams expecting input from us. */ - sigemptyset (&newblocked); if (filter_command) { struct sigaction act; + sigemptyset (&newblocked); sigaction (SIGPIPE, NULL, &act); if (act.sa_handler != SIG_IGN) sigaddset (&newblocked, SIGPIPE); + sigprocmask (SIG_BLOCK, &newblocked, &oldblocked); } - sigprocmask (SIG_BLOCK, &newblocked, &oldblocked); switch (split_type) { @@ -1264,8 +1264,6 @@ main (int argc, char **argv) abort (); } - sigprocmask (SIG_SETMASK, &oldblocked, NULL); - if (close (STDIN_FILENO) != 0) error (EXIT_FAILURE, errno, "%s", infile); closeout (NULL, output_desc, filter_pid, outfile); diff --git a/tests/split/filter b/tests/split/filter index 4c25c5f..0614841 100755 --- a/tests/split/filter +++ b/tests/split/filter @@ -43,4 +43,8 @@ done split -e -n 10 --filter='xz > $FILE.xz' /dev/null || fail=1 stat x?? 2>/dev/null && fail=1 +# Ensure SIGPIPEs sent by the children don't propagate back +# where they would result in a non zero exit from split. +yes | head -n200K | split -b1G --filter='head -c1 >/dev/null' || fail=1 + Exit $fail -- 1.7.4
