From cee7bfa9f0e5dc0ec8f8641327d1dba56dc4510d Mon Sep 17 00:00:00 2001
From: Todd Gamblin <tgamblin@llnl.gov>
Date: Mon, 18 Jan 2016 00:01:30 -0800
Subject: [PATCH] Simplify output redirection in spack.util.executable

- By default inherit parent's input/output descriptor
- Only use pipes if we need to return output.
- Allows subprocesses (like emacsclient) to detect terminal correctly
---
 lib/spack/spack/compiler.py        |  2 +-
 lib/spack/spack/util/executable.py | 25 ++++++++++---------------
 2 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py
index b9abf943e8..a665f6062d 100644
--- a/lib/spack/spack/compiler.py
+++ b/lib/spack/spack/compiler.py
@@ -51,7 +51,7 @@ def _verify_executables(*paths):
 def get_compiler_version(compiler_path, version_arg, regex='(.*)'):
     if not compiler_path in _version_cache:
         compiler = Executable(compiler_path)
-        output = compiler(version_arg, return_output=True, error=None)
+        output = compiler(version_arg, return_output=True, error=os.devnull)
 
         match = re.search(regex, output)
         _version_cache[compiler_path] = match.group(1) if match else 'unknown'
diff --git a/lib/spack/spack/util/executable.py b/lib/spack/spack/util/executable.py
index 35bf086616..ba765eb662 100644
--- a/lib/spack/spack/util/executable.py
+++ b/lib/spack/spack/util/executable.py
@@ -60,16 +60,16 @@ def __call__(self, *args, **kwargs):
         fail_on_error = kwargs.get("fail_on_error", True)
         ignore_errors = kwargs.get("ignore_errors", ())
 
-        output        = kwargs.get("output", sys.stdout)
-        error         = kwargs.get("error", sys.stderr)
+        # Default values of None says to keep parent's file descriptors.
+        output        = kwargs.get("output", None)
+        error         = kwargs.get("error", None)
         input         = kwargs.get("input", None)
 
         def streamify(arg, mode):
             if isinstance(arg, basestring):
                 return open(arg, mode), True
-            elif arg is None and mode != 'r':
-                return open(os.devnull, mode), True
-            return arg, False
+            else:
+                return arg, False
         output, ostream = streamify(output, 'w')
         error,  estream = streamify(error,  'w')
         input,  istream = streamify(input,  'r')
@@ -92,19 +92,14 @@ def streamify(arg, mode):
         tty.debug(cmd_line)
 
         try:
+            if return_output:
+                output = subprocess.PIPE
+
             proc = subprocess.Popen(
-                cmd,
-                stdin=input,
-                stderr=subprocess.PIPE,
-                stdout=subprocess.PIPE)
+                cmd, stdin=input, stderr=error, stdout=output)
             out, err = proc.communicate()
-            self.returncode = proc.returncode
-
-            if not return_output:
-                output.write(out)
-            error.write(err)
 
-            rc = proc.returncode
+            rc = self.returncode = proc.returncode
             if fail_on_error and rc != 0 and (rc not in ignore_errors):
                 raise ProcessError("Command exited with status %d:"
                                    % proc.returncode, cmd_line)
-- 
GitLab