summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2012-09-11 23:24:44 -0700
committerZac Medico <zmedico@gentoo.org>2012-09-11 23:24:44 -0700
commit09de8dc47ec48af2276dfa098dd5e1d3d09ddbdd (patch)
treeb3426b3ae1071f15fa20d9ef99a9eae73562b521
parent5614fa2d7cef0b509136fd00c52a8436d41a3647 (diff)
downloadportage-09de8dc47ec48af2276dfa098dd5e1d3d09ddbdd.tar.gz
portage-09de8dc47ec48af2276dfa098dd5e1d3d09ddbdd.tar.bz2
portage-09de8dc47ec48af2276dfa098dd5e1d3d09ddbdd.zip
Replace getstatusoutput with unicode safe Popen.
This fixes potential issues similar to those reported in bug #310789.
-rw-r--r--pym/portage/__init__.py38
-rw-r--r--pym/portage/checksum.py17
-rw-r--r--pym/portage/data.py23
-rw-r--r--pym/portage/tests/lint/test_bash_syntax.py16
-rw-r--r--pym/portage/tests/lint/test_import_modules.py2
-rw-r--r--pym/portage/util/__init__.py21
6 files changed, 81 insertions, 36 deletions
diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py
index 43c5af30e..97352b273 100644
--- a/pym/portage/__init__.py
+++ b/pym/portage/__init__.py
@@ -1,5 +1,5 @@
# portage.py -- core Portage functionality
-# Copyright 1998-2011 Gentoo Foundation
+# Copyright 1998-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
VERSION="HEAD"
@@ -16,14 +16,6 @@ try:
errno.ESTALE = -1
import re
import types
-
- # Try the commands module first, since this allows us to eliminate
- # the subprocess module from the baseline imports under python2.
- try:
- from commands import getstatusoutput as subprocess_getstatusoutput
- except ImportError:
- from subprocess import getstatusoutput as subprocess_getstatusoutput
-
import platform
# Temporarily delete these imports, to ensure that only the
@@ -114,6 +106,7 @@ try:
'cpv_getkey@getCPFromCPV,endversion_keys,' + \
'suffix_value@endversion,pkgcmp,pkgsplit,vercmp,ververify',
'portage.xpak',
+ 'subprocess',
'time',
)
@@ -354,8 +347,16 @@ if platform.system() in ('FreeBSD',):
@classmethod
def chflags(cls, path, flags, opts=""):
- cmd = 'chflags %s %o %s' % (opts, flags, _shell_quote(path))
- status, output = subprocess_getstatusoutput(cmd)
+ cmd = ['chflags', opts, flags, path]
+ encoding = _encodings['fs']
+ if sys.hexversion < 0x3000000 or sys.hexversion >= 0x3020000:
+ # Python 3.1 does not support bytes in Popen args.
+ cmd = [_unicode_encode(x, encoding=encoding, errors='strict')
+ for x in cmd]
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ output = proc.communicate()[0]
+ status = proc.wait()
if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK:
return
# Try to generate an ENOENT error if appropriate.
@@ -368,6 +369,7 @@ if platform.system() in ('FreeBSD',):
raise portage.exception.CommandNotFound('chflags')
# Now we're not sure exactly why it failed or what
# the real errno was, so just report EPERM.
+ output = _unicode_decode(output, encoding=encoding)
e = OSError(errno.EPERM, output)
e.errno = errno.EPERM
e.filename = path
@@ -547,11 +549,19 @@ if VERSION == 'HEAD':
if VERSION is not self:
return VERSION
if os.path.isdir(os.path.join(PORTAGE_BASE_PATH, '.git')):
- status, output = subprocess_getstatusoutput((
- "cd %s ; git describe --tags || exit $? ; " + \
+ encoding = _encodings['fs']
+ cmd = [BASH_BINARY, "-c", ("cd %s ; git describe --tags || exit $? ; " + \
"if [ -n \"`git diff-index --name-only --diff-filter=M HEAD`\" ] ; " + \
"then echo modified ; git rev-list --format=%%ct -n 1 HEAD ; fi ; " + \
- "exit 0") % _shell_quote(PORTAGE_BASE_PATH))
+ "exit 0") % _shell_quote(PORTAGE_BASE_PATH)]
+ if sys.hexversion < 0x3000000 or sys.hexversion >= 0x3020000:
+ # Python 3.1 does not support bytes in Popen args.
+ cmd = [_unicode_encode(x, encoding=encoding, errors='strict')
+ for x in cmd]
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ output = _unicode_decode(proc.communicate()[0], encoding=encoding)
+ status = proc.wait()
if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK:
output_lines = output.splitlines()
if output_lines:
diff --git a/pym/portage/checksum.py b/pym/portage/checksum.py
index 144e6336f..30a9234e1 100644
--- a/pym/portage/checksum.py
+++ b/pym/portage/checksum.py
@@ -10,6 +10,8 @@ from portage import _encodings
from portage import _unicode_encode
import errno
import stat
+import sys
+import subprocess
import tempfile
#dict of all available hash functions
@@ -163,11 +165,18 @@ hashfunc_map["size"] = getsize
prelink_capable = False
if os.path.exists(PRELINK_BINARY):
- results = portage.subprocess_getstatusoutput(
- "%s --version > /dev/null 2>&1" % (PRELINK_BINARY,))
- if (results[0] >> 8) == 0:
+ cmd = [PRELINK_BINARY, "--version"]
+ if sys.hexversion < 0x3000000 or sys.hexversion >= 0x3020000:
+ # Python 3.1 does not support bytes in Popen args.
+ cmd = [_unicode_encode(x, encoding=_encodings['fs'], errors='strict')
+ for x in cmd]
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ proc.communicate()
+ status = proc.wait()
+ if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK:
prelink_capable=1
- del results
+ del cmd, proc, status
def is_prelinkable_elf(filename):
f = _open_file(filename)
diff --git a/pym/portage/data.py b/pym/portage/data.py
index c4d967a1b..b922ff8e9 100644
--- a/pym/portage/data.py
+++ b/pym/portage/data.py
@@ -1,13 +1,14 @@
# data.py -- Calculated/Discovered Data Values
-# Copyright 1998-2011 Gentoo Foundation
+# Copyright 1998-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-import os, pwd, grp, platform
+import os, pwd, grp, platform, sys
import portage
portage.proxy.lazyimport.lazyimport(globals(),
'portage.output:colorize',
'portage.util:writemsg',
+ 'subprocess'
)
from portage.localization import _
@@ -129,10 +130,20 @@ def _get_global(k):
# Get a list of group IDs for the portage user. Do not use
# grp.getgrall() since it is known to trigger spurious
# SIGPIPE problems with nss_ldap.
- mystatus, myoutput = \
- portage.subprocess_getstatusoutput("id -G %s" % _portage_username)
- if mystatus == os.EX_OK:
- for x in myoutput.split():
+ cmd = ["id", "-G", _portage_username]
+ encoding = portage._encodings['content']
+ if sys.hexversion < 0x3000000 or sys.hexversion >= 0x3020000:
+ # Python 3.1 does not support bytes in Popen args.
+ cmd = [portage._unicode_encode(x,
+ encoding=encoding, errors='strict')
+ for x in cmd]
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ myoutput = proc.communicate()[0]
+ status = proc.wait()
+ if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK:
+ for x in portage._unicode_decode(myoutput,
+ encoding=encoding, errors='strict').split():
try:
v.append(int(x))
except ValueError:
diff --git a/pym/portage/tests/lint/test_bash_syntax.py b/pym/portage/tests/lint/test_bash_syntax.py
index 3acea6619..0d7d35a6d 100644
--- a/pym/portage/tests/lint/test_bash_syntax.py
+++ b/pym/portage/tests/lint/test_bash_syntax.py
@@ -3,13 +3,13 @@
from itertools import chain
import stat
+import subprocess
+import sys
from portage.const import BASH_BINARY, PORTAGE_BASE_PATH, PORTAGE_BIN_PATH
from portage.tests import TestCase
from portage import os
-from portage import subprocess_getstatusoutput
from portage import _encodings
-from portage import _shell_quote
from portage import _unicode_decode, _unicode_encode
class BashSyntaxTestCase(TestCase):
@@ -42,7 +42,15 @@ class BashSyntaxTestCase(TestCase):
f.close()
if line[:2] == '#!' and \
'bash' in line:
- cmd = "%s -n %s" % (_shell_quote(BASH_BINARY), _shell_quote(x))
- status, output = subprocess_getstatusoutput(cmd)
+ cmd = [BASH_BINARY, "-n", x]
+ if sys.hexversion < 0x3000000 or sys.hexversion >= 0x3020000:
+ # Python 3.1 does not support bytes in Popen args.
+ cmd = [_unicode_encode(x,
+ encoding=_encodings['fs'], errors='strict') for x in cmd]
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ output = _unicode_decode(proc.communicate()[0],
+ encoding=_encodings['fs'])
+ status = proc.wait()
self.assertEqual(os.WIFEXITED(status) and \
os.WEXITSTATUS(status) == os.EX_OK, True, msg=output)
diff --git a/pym/portage/tests/lint/test_import_modules.py b/pym/portage/tests/lint/test_import_modules.py
index 8d257c5a6..34261f464 100644
--- a/pym/portage/tests/lint/test_import_modules.py
+++ b/pym/portage/tests/lint/test_import_modules.py
@@ -1,4 +1,4 @@
-# Copyright 2011 Gentoo Foundation
+# Copyright 2011-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from portage.const import PORTAGE_PYM_PATH
diff --git a/pym/portage/util/__init__.py b/pym/portage/util/__init__.py
index 951a158a9..fee0bc7d2 100644
--- a/pym/portage/util/__init__.py
+++ b/pym/portage/util/__init__.py
@@ -31,11 +31,11 @@ import portage
portage.proxy.lazyimport.lazyimport(globals(),
'pickle',
'portage.dep:Atom',
- 'portage.util.listdir:_ignorecvs_dirs'
+ 'portage.util.listdir:_ignorecvs_dirs',
+ 'subprocess',
)
from portage import os
-from portage import subprocess_getstatusoutput
from portage import _encodings
from portage import _os_merge
from portage import _unicode_encode
@@ -1589,7 +1589,7 @@ def find_updated_config_files(target_root, config_protect):
If no configuration files needs to be updated, None is returned
"""
- os = _os_merge
+ encoding = _encodings['fs']
if config_protect:
# directories with some protect files in them
@@ -1621,10 +1621,17 @@ def find_updated_config_files(target_root, config_protect):
mycommand = "find '%s' -maxdepth 1 -name '._cfg????_%s'" % \
os.path.split(x.rstrip(os.path.sep))
mycommand += " ! -name '.*~' ! -iname '.*.bak' -print0"
- a = subprocess_getstatusoutput(mycommand)
-
- if a[0] == 0:
- files = a[1].split('\0')
+ cmd = shlex_split(mycommand)
+ if sys.hexversion < 0x3000000 or sys.hexversion >= 0x3020000:
+ # Python 3.1 does not support bytes in Popen args.
+ cmd = [_unicode_encode(x, encoding=encoding, errors='strict')
+ for x in cmd]
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ output = _unicode_decode(proc.communicate()[0], encoding=encoding)
+ status = proc.wait()
+ if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK:
+ files = output.split('\0')
# split always produces an empty string as the last element
if files and not files[-1]:
del files[-1]