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/
This commit is contained in:
parent
c2c013970e
commit
cb713bdace
1 changed files with 3 additions and 1 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import sys, os, errno, stat
|
import sys, os, errno, stat, signal
|
||||||
import vars, jwack, state
|
import vars, jwack, state
|
||||||
from helpers import unlink, close_on_exec, join
|
from helpers import unlink, close_on_exec, join
|
||||||
from log import log, log_, debug, debug2, err, warn
|
from log import log, log_, debug, debug2, err, warn
|
||||||
|
|
@ -190,6 +190,7 @@ class BuildJob:
|
||||||
def run():
|
def run():
|
||||||
os.chdir(vars.BASE)
|
os.chdir(vars.BASE)
|
||||||
os.environ['REDO_DEPTH'] = vars.DEPTH + ' '
|
os.environ['REDO_DEPTH'] = vars.DEPTH + ' '
|
||||||
|
signal.signal(signal.SIGPIPE, signal.SIG_DFL) # python ignores SIGPIPE
|
||||||
os.execvp(argv[0], argv)
|
os.execvp(argv[0], argv)
|
||||||
assert(0)
|
assert(0)
|
||||||
# returns only if there's an exception
|
# returns only if there's an exception
|
||||||
|
|
@ -214,6 +215,7 @@ class BuildJob:
|
||||||
os.dup2(self.f.fileno(), 1)
|
os.dup2(self.f.fileno(), 1)
|
||||||
os.close(self.f.fileno())
|
os.close(self.f.fileno())
|
||||||
close_on_exec(1, False)
|
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))
|
if vars.VERBOSE or vars.XTRACE: log_('* %s\n' % ' '.join(self.argv))
|
||||||
os.execvp(self.argv[0], self.argv)
|
os.execvp(self.argv[0], self.argv)
|
||||||
assert(0)
|
assert(0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue