dispatch_conf: emulate getstatusoutput with Popen
authorZac Medico <zmedico@gentoo.org>
Sat, 31 Mar 2012 17:22:13 +0000 (10:22 -0700)
committerZac Medico <zmedico@gentoo.org>
Sat, 31 Mar 2012 17:22:13 +0000 (10:22 -0700)
This will fix bug #410315.

pym/portage/dispatch_conf.py

index 3d53f6405a4976d89bc6bae56058cf1c89ec03f4..cc98fad16693289777a42c6e89c9cb9eb7c9600c 100644 (file)
@@ -1,5 +1,5 @@
 # archive_conf.py -- functionality common to archive-conf and dispatch-conf
-# Copyright 2003-2011 Gentoo Foundation
+# Copyright 2003-2012 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 
@@ -8,7 +8,7 @@
 
 from __future__ import print_function
 
-import os, sys, shutil
+import os, shutil, subprocess, sys
 
 import portage
 from portage.env.loaders import KeyValuePairFileLoader
@@ -26,17 +26,17 @@ DIFF3_MERGE = "diff3 -mE '%s' '%s' '%s' > '%s'"
 def diffstatusoutput(cmd, file1, file2):
     """
     Execute the string cmd in a shell with getstatusoutput() and return a
-    2-tuple (status, output). If getstatusoutput() raises
-    UnicodeDecodeError (known to happen with python3.1), return a
-    2-tuple (1, 1). This provides a simple way to check for non-zero
-    output length of diff commands, while providing simple handling of
-    UnicodeDecodeError when necessary.
+    2-tuple (status, output).
     """
-    try:
-        status, output = portage.subprocess_getstatusoutput(cmd % (file1, file2))
-        return (status, output)
-    except UnicodeDecodeError:
-        return (1, 1)
+    # Use Popen to emulate getstatusoutput(), since getstatusoutput() may
+    # raise a UnicodeDecodeError which makes the output inaccessible.
+    proc = subprocess.Popen(portage._unicode_encode(cmd % (file1, file2)),
+        stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
+    output = portage._unicode_decode(proc.communicate()[0])
+    if output and output[-1] == "\n":
+        # getstatusoutput strips one newline
+        output = output[:-1]
+    return (proc.wait(), output)
 
 def read_config(mandatory_opts):
     eprefix = portage.const.EPREFIX