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.
This commit is contained in:
Jonathan Oddy 2018-08-03 17:35:34 +01:00 committed by Toshio Kuratomi
parent 1015c50034
commit f2dccb90e8
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 re
import shlex
import signal
import subprocess
import sys
import types
@ -2681,6 +2682,11 @@ class AnsibleModule(object):
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,
use_unsafe_shell=False, prompt_regex=None, environ_update=None, umask=None, encoding='utf-8', errors='surrogate_or_strict',
expand_user_and_vars=True):
@ -2825,6 +2831,7 @@ class AnsibleModule(object):
stdin=st_in,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
preexec_fn=self._restore_signal_handlers,
)
# store the pwd