Restores SIGPIPE on script processes

There is an issue https://bugs.python.org/issue1652
in Python 2.7 which was resolved in Py3.

By default Python sets SIGPIPE to SIG_IGN on startup, because
it prefers to check every write and raise an IOError exception rather
than taking SIGPIPE. This is all well and good for Python itself.
However, non-Python Unix subprocesses generally expect to have
SIGPIPE set to the default action, since that's what will happen if
they're started from a normal shell.

As a result scripts with piping that is terminated in reverse chain
order are never exit.

See more info here:
http://www.enricozini.org/blog/2009/debian/python-pipes/

Closes-Bug: #1524347
Change-Id: Ia015e7fd46912f6a0be97a6b9c297f8d14fd3f7c
This commit is contained in:
Stan Lagun 2016-03-22 16:47:49 +03:00
parent 6def6725ed
commit 0bbfed3bf4
1 changed files with 13 additions and 7 deletions

View File

@ -14,6 +14,7 @@
# limitations under the License. # limitations under the License.
import os import os
import signal
import stat import stat
import subprocess import subprocess
import sys import sys
@ -52,13 +53,18 @@ class ApplicationExecutor(object):
script_name = os.path.relpath(self._path) script_name = os.path.relpath(self._path)
LOG.debug("Starting '{0}' script execution".format(script_name)) LOG.debug("Starting '{0}' script execution".format(script_name))
process = subprocess.Popen( popen_kwargs = {
app, 'stdout': stdout,
stdout=stdout, 'stderr': stderr,
stderr=stderr, 'universal_newlines': True,
universal_newlines=True, 'cwd': dir_name,
cwd=dir_name, 'shell': True
shell=True) }
if os.name != 'nt':
popen_kwargs['preexec_fn'] = lambda: signal.signal(
signal.SIGPIPE, signal.SIG_DFL)
process = subprocess.Popen(app, **popen_kwargs)
stdout, stderr = process.communicate(input) stdout, stderr = process.communicate(input)
retcode = process.poll() retcode = process.poll()
LOG.debug("Script {0} execution finished " LOG.debug("Script {0} execution finished "