Browse Source

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
tags/2015.1.1^0
Stan Lagun 3 years ago
parent
commit
75e7e04695
1 changed files with 13 additions and 7 deletions
  1. 13
    7
      muranoagent/executors/application/__init__.py

+ 13
- 7
muranoagent/executors/application/__init__.py View File

@@ -14,6 +14,7 @@
14 14
 # limitations under the License.
15 15
 
16 16
 import os
17
+import signal
17 18
 import stat
18 19
 import subprocess
19 20
 import sys
@@ -52,13 +53,18 @@ class ApplicationExecutor(object):
52 53
         script_name = os.path.relpath(self._path)
53 54
         LOG.debug("Starting '{0}' script execution".format(script_name))
54 55
 
55
-        process = subprocess.Popen(
56
-            app,
57
-            stdout=stdout,
58
-            stderr=stderr,
59
-            universal_newlines=True,
60
-            cwd=dir_name,
61
-            shell=True)
56
+        popen_kwargs = {
57
+            'stdout': stdout,
58
+            'stderr': stderr,
59
+            'universal_newlines': True,
60
+            'cwd': dir_name,
61
+            'shell': True
62
+        }
63
+        if os.name != 'nt':
64
+            popen_kwargs['preexec_fn'] = lambda: signal.signal(
65
+                signal.SIGPIPE, signal.SIG_DFL)
66
+
67
+        process = subprocess.Popen(app, **popen_kwargs)
62 68
         stdout, stderr = process.communicate(input)
63 69
         retcode = process.poll()
64 70
         LOG.debug("Script {0} execution finished "

Loading…
Cancel
Save