commit: e5ba8d096e56495a9b516cea818d48e104d62bca Author: Michał Górny <mgorny <AT> gentoo <DOT> org> AuthorDate: Sun Nov 15 21:03:42 2015 +0000 Commit: Michał Górny <mgorny <AT> gentoo <DOT> org> CommitDate: Sun Nov 15 21:18:48 2015 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=e5ba8d09
EAPI 6: Enforce posixish LC_CTYPE pym/portage/package/ebuild/config.py | 13 ++++++++++++- pym/portage/util/locale.py | 23 ++++++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py index 095de37..1827043 100644 --- a/pym/portage/package/ebuild/config.py +++ b/pym/portage/package/ebuild/config.py @@ -24,7 +24,7 @@ portage.proxy.lazyimport.lazyimport(globals(), 'portage.dep.soname.SonameAtom:SonameAtom', 'portage.dbapi.vartree:vartree', 'portage.package.ebuild.doebuild:_phase_func_map', - 'portage.util.locale:split_LC_ALL', + 'portage.util.locale:check_locale,split_LC_ALL', ) from portage import bsd_chflags, \ load_mod, os, selinux, _unicode_decode @@ -2773,6 +2773,17 @@ class config(object): if eapi_attrs.posixish_locale: split_LC_ALL(mydict) mydict["LC_COLLATE"] = "C" + if not check_locale(silent=True, env=mydict): + # try another locale + for l in ("C.UTF-8", "en_US.UTF-8", "en_GB.UTF-8", "C"): + mydict["LC_CTYPE"] = l + if check_locale(silent=True, env=mydict): + # TODO: output the following only once +# writemsg(_("!!! LC_CTYPE unsupported, using %s instead\n") +# % mydict["LC_CTYPE"]) + break + else: + raise AssertionError("C locale did not pass the test!") return mydict diff --git a/pym/portage/util/locale.py b/pym/portage/util/locale.py index d902db8..27a2806 100644 --- a/pym/portage/util/locale.py +++ b/pym/portage/util/locale.py @@ -8,6 +8,7 @@ locale. """ from __future__ import unicode_literals +import locale import logging import os import textwrap @@ -26,7 +27,7 @@ locale_categories = ( ) -def _check_locale(): +def _check_locale(silent): """ The inner locale check function. """ @@ -44,6 +45,9 @@ def _check_locale(): ruc = [libc.toupper(c) for c in lc] if lc != rlc or uc != ruc: + if silent: + return False + msg = ("WARNING: The LC_CTYPE variable is set to a locale " + "that specifies transformation between lowercase " + "and uppercase ASCII characters that is different than " + @@ -71,7 +75,7 @@ def _check_locale(): return True -def check_locale(): +def check_locale(silent=False, env=None): """ Check whether the locale is sane. Returns True if it is, prints warning and returns False if it is not. Returns None if the check @@ -81,7 +85,20 @@ def check_locale(): pid = os.fork() if pid == 0: try: - ret = _check_locale() + if env is not None: + for v in ("LC_ALL", "LC_CTYPE", "LANG"): + if v in env: + mylocale = env[v] + break + else: + mylocale = "C" + + try: + locale.setlocale(locale.LC_CTYPE, mylocale) + except locale.Error: + os._exit(2) + + ret = _check_locale(silent) if ret is None: os._exit(2) else: