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.
pull/46986/head
Jonathan Oddy 6 years ago committed by Toshio Kuratomi
parent 1015c50034
commit f2dccb90e8

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

@ -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',
expand_user_and_vars=True): expand_user_and_vars=True):
@ -2825,6 +2831,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

Loading…
Cancel
Save