1 |
--- |
2 |
pym/portage/package/ebuild/config.py | 17 ++++++++++++++--- |
3 |
pym/portage/util/locale.py | 30 +++++++++++++++++++++++++++++- |
4 |
2 files changed, 43 insertions(+), 4 deletions(-) |
5 |
|
6 |
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py |
7 |
index 4d07638..dd437a9 100644 |
8 |
--- a/pym/portage/package/ebuild/config.py |
9 |
+++ b/pym/portage/package/ebuild/config.py |
10 |
@@ -24,7 +24,7 @@ portage.proxy.lazyimport.lazyimport(globals(), |
11 |
'portage.dep.soname.SonameAtom:SonameAtom', |
12 |
'portage.dbapi.vartree:vartree', |
13 |
'portage.package.ebuild.doebuild:_phase_func_map', |
14 |
- 'portage.util.locale:split_LC_ALL', |
15 |
+ 'portage.util.locale:check_locale_env,split_LC_ALL', |
16 |
) |
17 |
from portage import bsd_chflags, \ |
18 |
load_mod, os, selinux, _unicode_decode |
19 |
@@ -2770,9 +2770,20 @@ class config(object): |
20 |
if phase_func is not None: |
21 |
mydict["EBUILD_PHASE_FUNC"] = phase_func |
22 |
|
23 |
- if eapi_attrs.requires_posixish_locale: |
24 |
+ if eapi_attrs.posixish_locale: |
25 |
split_LC_ALL(mydict) |
26 |
- mysettings["LC_COLLATE"] = "C" |
27 |
+ mydict["LC_COLLATE"] = "C" |
28 |
+ if not check_locale_env(mydict): |
29 |
+ # try another locale |
30 |
+ for l in ("C.UTF-8", "en_US.UTF-8", "en_GB.UTF-8", "C"): |
31 |
+ mydict["LC_CTYPE"] = l |
32 |
+ if check_locale_env(mydict): |
33 |
+ # TODO: output the following only once |
34 |
+# writemsg(_("!!! LC_CTYPE unsupported, using %s instead\n") |
35 |
+# % mydict["LC_CTYPE"]) |
36 |
+ break |
37 |
+ else: |
38 |
+ raise AssertionError("C locale did not pass the test!") |
39 |
|
40 |
return mydict |
41 |
|
42 |
diff --git a/pym/portage/util/locale.py b/pym/portage/util/locale.py |
43 |
index 570f6f0..bcf05d1 100644 |
44 |
--- a/pym/portage/util/locale.py |
45 |
+++ b/pym/portage/util/locale.py |
46 |
@@ -9,7 +9,9 @@ get_ro_checker(). |
47 |
""" |
48 |
from __future__ import unicode_literals |
49 |
|
50 |
+import locale |
51 |
import logging |
52 |
+import os |
53 |
import textwrap |
54 |
|
55 |
from portage.util import writemsg_level |
56 |
@@ -25,7 +27,7 @@ locale_categories = ( |
57 |
) |
58 |
|
59 |
|
60 |
-def check_locale(): |
61 |
+def check_locale(silent=False): |
62 |
""" |
63 |
Check whether the locale is sane. Returns True if it is, prints |
64 |
warning and returns False if it is not. Returns None if the check |
65 |
@@ -45,6 +47,9 @@ def check_locale(): |
66 |
ruc = [libc.toupper(c) for c in lc] |
67 |
|
68 |
if lc != rlc or uc != ruc: |
69 |
+ if silent: |
70 |
+ return False |
71 |
+ |
72 |
msg = ("WARNING: The LC_CTYPE variable is set to a locale " + |
73 |
"that specifies transformation between lowercase " + |
74 |
"and uppercase ASCII characters that is different than " + |
75 |
@@ -72,6 +77,29 @@ def check_locale(): |
76 |
return True |
77 |
|
78 |
|
79 |
+def check_locale_env(env): |
80 |
+ """ |
81 |
+ Check whether locale specified in passed environment variable dict |
82 |
+ is sane. Wraps check_locale() in a subprocess. |
83 |
+ """ |
84 |
+ pid = os.fork() |
85 |
+ if pid == 0: |
86 |
+ try: |
87 |
+ locale.setlocale(locale.LC_CTYPE, |
88 |
+ env.get("LC_CTYPE", env.get("LANG", "C"))) |
89 |
+ except locale.Error: |
90 |
+ os._exit(2) |
91 |
+ |
92 |
+ ret = check_locale(silent=True) |
93 |
+ if ret is not None and not ret: |
94 |
+ os._exit(1) |
95 |
+ os._exit(0) |
96 |
+ |
97 |
+ pid2, status = os.waitpid(pid, 0) |
98 |
+ assert pid == pid2 |
99 |
+ return os.WEXITSTATUS(status) == 0 |
100 |
+ |
101 |
+ |
102 |
def split_LC_ALL(env): |
103 |
""" |
104 |
Replace LC_ALL with split-up LC_* variables if it is defined. |
105 |
-- |
106 |
2.6.3 |