[stable-2.7] Restore SIGPIPE handler to DFL on POpen

Python sets the SIGPIPE handler to SIG_IGN. On execv() signal handlers are
reset to their defaults, EXCEPT those that are SIG_IGN which are left ignored.
In Python 3 subprocess.popen explicitly resets the SIGPIPE handler to SIG_DFL,
but unfortunately in Python 2.7 it does not. This leads to subprocesses being
executed with SIGPIPE ignored. This is often a problem with bash scripts which
rely on SIGPIPE to terminate commands in a pipe, but can easily be a problem
with other applications.

This implements the Python 3 behaviour for Python 2.7 by using a preexec_fn.
(cherry picked from commit f2dccb9)

Co-authored-by: Jonathan Oddy <jonathan.oddy@transferwise.com>
This commit is contained in:
Jonathan Oddy 2018-08-03 17:35:34 +01:00 committed by Toshio Kuratomi
parent da07b58c3b
commit 60e7f43998
2 changed files with 9 additions and 0 deletions

View file

@ -0,0 +1,2 @@
bugfixes:
- Restore SIGPIPE to SIG_DFL when creating subprocesses to avoid it being ignored under Python 2.

View file

@ -68,6 +68,7 @@ import locale
import os import os
import re import re
import shlex import shlex
import signal
import subprocess import subprocess
import sys import sys
import types import types
@ -2681,6 +2682,11 @@ class AnsibleModule(object):
return self._clean return self._clean
def _restore_signal_handlers(self):
# Reset SIGPIPE to SIG_DFL, otherwise in Python2.7 it gets ignored in subprocesses.
if PY2 and sys.platform != 'win32':
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
def run_command(self, args, check_rc=False, close_fds=True, executable=None, data=None, binary_data=False, path_prefix=None, cwd=None, def run_command(self, args, check_rc=False, close_fds=True, executable=None, data=None, binary_data=False, path_prefix=None, cwd=None,
use_unsafe_shell=False, prompt_regex=None, environ_update=None, umask=None, encoding='utf-8', errors='surrogate_or_strict'): use_unsafe_shell=False, prompt_regex=None, environ_update=None, umask=None, encoding='utf-8', errors='surrogate_or_strict'):
''' '''
@ -2816,6 +2822,7 @@ class AnsibleModule(object):
stdin=st_in, stdin=st_in,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
preexec_fn=self._restore_signal_handlers,
) )
# store the pwd # store the pwd