]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/locale-setup.c
util-lib: wrap personality() to fix up broken glibc error handling (#6766)
[thirdparty/systemd.git] / src / core / locale-setup.c
CommitLineData
72bca11b
LP
1/***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
72bca11b
LP
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 14 Lesser General Public License for more details.
72bca11b 15
5430f7f2 16 You should have received a copy of the GNU Lesser General Public License
72bca11b
LP
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
72bca11b 20#include <errno.h>
07630cea 21#include <stdlib.h>
72bca11b 22
bcd8e6d1 23#include "env-util.h"
07630cea 24#include "fileio.h"
cf0fbc49 25#include "locale-setup.h"
a3428668 26#include "locale-util.h"
07630cea
LP
27#include "string-util.h"
28#include "strv.h"
29#include "util.h"
30#include "virt.h"
72bca11b 31
e21fea24 32int locale_setup(char ***environment) {
bcd8e6d1 33 char **add;
a3428668 34 char *variables[_VARIABLE_LC_MAX] = {};
d885ac66 35 int r = 0, i;
72bca11b 36
75f86906 37 if (detect_container() <= 0) {
39d99a07 38 r = parse_env_file("/proc/cmdline", WHITESPACE,
39d99a07
LP
39 "locale.LANG", &variables[VARIABLE_LANG],
40 "locale.LANGUAGE", &variables[VARIABLE_LANGUAGE],
41 "locale.LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
42 "locale.LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
43 "locale.LC_TIME", &variables[VARIABLE_LC_TIME],
44 "locale.LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
45 "locale.LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
46 "locale.LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
47 "locale.LC_PAPER", &variables[VARIABLE_LC_PAPER],
48 "locale.LC_NAME", &variables[VARIABLE_LC_NAME],
49 "locale.LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
50 "locale.LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
51 "locale.LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
52 "locale.LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
53 NULL);
54
55 if (r < 0 && r != -ENOENT)
da927ba9 56 log_warning_errno(r, "Failed to read /proc/cmdline: %m");
39d99a07 57 }
ce8a6aa1
LP
58
59 /* Hmm, nothing set on the kernel cmd line? Then let's
fd5bf055 60 * try /etc/locale.conf */
39d99a07
LP
61 if (r <= 0) {
62 r = parse_env_file("/etc/locale.conf", NEWLINE,
63 "LANG", &variables[VARIABLE_LANG],
64 "LANGUAGE", &variables[VARIABLE_LANGUAGE],
65 "LC_CTYPE", &variables[VARIABLE_LC_CTYPE],
66 "LC_NUMERIC", &variables[VARIABLE_LC_NUMERIC],
67 "LC_TIME", &variables[VARIABLE_LC_TIME],
68 "LC_COLLATE", &variables[VARIABLE_LC_COLLATE],
69 "LC_MONETARY", &variables[VARIABLE_LC_MONETARY],
70 "LC_MESSAGES", &variables[VARIABLE_LC_MESSAGES],
71 "LC_PAPER", &variables[VARIABLE_LC_PAPER],
72 "LC_NAME", &variables[VARIABLE_LC_NAME],
73 "LC_ADDRESS", &variables[VARIABLE_LC_ADDRESS],
74 "LC_TELEPHONE", &variables[VARIABLE_LC_TELEPHONE],
75 "LC_MEASUREMENT", &variables[VARIABLE_LC_MEASUREMENT],
76 "LC_IDENTIFICATION", &variables[VARIABLE_LC_IDENTIFICATION],
77 NULL);
78
79 if (r < 0 && r != -ENOENT)
da927ba9 80 log_warning_errno(r, "Failed to read /etc/locale.conf: %m");
ce8a6aa1
LP
81 }
82
bcd8e6d1 83 add = NULL;
a3428668 84 for (i = 0; i < _VARIABLE_LC_MAX; i++) {
bcd8e6d1
LP
85 char *s;
86
e21fea24
KS
87 if (!variables[i])
88 continue;
89
605405c6 90 s = strjoin(locale_variable_to_string(i), "=", variables[i]);
bcd8e6d1
LP
91 if (!s) {
92 r = -ENOMEM;
93 goto finish;
94 }
95
6e18964d 96 if (strv_consume(&add, s) < 0) {
bcd8e6d1
LP
97 r = -ENOMEM;
98 goto finish;
99 }
100 }
101
102 if (!strv_isempty(add)) {
103 char **e;
104
105 e = strv_env_merge(2, *environment, add);
106 if (!e) {
e21fea24
KS
107 r = -ENOMEM;
108 goto finish;
109 }
110
bcd8e6d1
LP
111 strv_free(*environment);
112 *environment = e;
72bca11b 113 }
8780d48d 114
72bca11b
LP
115 r = 0;
116
117finish:
bcd8e6d1
LP
118 strv_free(add);
119
a3428668 120 for (i = 0; i < _VARIABLE_LC_MAX; i++)
72bca11b
LP
121 free(variables[i]);
122
123 return r;
124}