From cb713bdaceea9bd37a2c158697ccb90da14ef047 Mon Sep 17 00:00:00 2001 From: Travis Cross Date: Fri, 28 Jun 2013 01:48:41 +0000 Subject: [PATCH] Restore SIGPIPE default action before exec(3) Python chooses to ignore SIGPIPE, however most unix processes expect to terminate on the signal. Therefore failing to restore the default action results in surprising behavior. For example, we expect `dd if=/dev/zero | head -c1` to return immediately. However, prior to this commit, that pipeline would hang forever. Insidious forms of data corruption or loss were also possible. See: http://www.chiark.greenend.org.uk/ucgi/~cjwatson/blosxom/2009-07-02-python-sigpipe.html http://blog.nelhage.com/2010/02/a-very-subtle-bug/ --- builder.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/builder.py b/builder.py index 523c8cf..e3c9df7 100644 --- a/builder.py +++ b/builder.py @@ -1,4 +1,4 @@ -import sys, os, errno, stat +import sys, os, errno, stat, signal import vars, jwack, state from helpers import unlink, close_on_exec, join from log import log, log_, debug, debug2, err, warn @@ -190,6 +190,7 @@ class BuildJob: def run(): os.chdir(vars.BASE) os.environ['REDO_DEPTH'] = vars.DEPTH + ' ' + signal.signal(signal.SIGPIPE, signal.SIG_DFL) # python ignores SIGPIPE os.execvp(argv[0], argv) assert(0) # returns only if there's an exception @@ -214,6 +215,7 @@ class BuildJob: os.dup2(self.f.fileno(), 1) os.close(self.f.fileno()) close_on_exec(1, False) + signal.signal(signal.SIGPIPE, signal.SIG_DFL) # python ignores SIGPIPE if vars.VERBOSE or vars.XTRACE: log_('* %s\n' % ' '.join(self.argv)) os.execvp(self.argv[0], self.argv) assert(0)