From b775f93c2269e7fc9dbc704464179babe2c1ca3d Mon Sep 17 00:00:00 2001 From: Jakub Krcma Date: Fri, 28 Feb 2020 10:50:27 +0100 Subject: [PATCH] Set locale env variables in correct order This commit aims to fix the use case of setting multiple environment variables in locale settings. As described in manpages, consider the following content of `/etc/locale.conf`: LANG=de_DE.UTF-8 LC_MESSAGES=en_US.UTF-8 The previous behavior caused only `LANG` to be set, leaving the other variables intact. I am not familiar how exactly shell interprets setting values on these values, but the value of `LC_MESSAGES` in the example was never applied to the environment. The only way how to make it working was to execute `unset LANG` before the `locale.conf` variables were set. This code snippet is heavily inspired by https://github.com/linuxdeepin/lightdm/blob/810f9b171feb779e48eba1dca38eb37d6d027d1a/src/session-child.c --- src/login.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/login.c b/src/login.c index 57219ae..c492647 100644 --- a/src/login.c +++ b/src/login.c @@ -207,11 +207,29 @@ void pam_diagnose(int error, struct term_buf* buf) void env_init(struct passwd* pwd) { + // borrowed from + // https://github.com/linuxdeepin/lightdm/blob/810f9b171feb779e48eba1dca38eb37d6d027d1a/src/session-child.c + static const char* const locale_var_names[] = { + "LC_PAPER", + "LC_NAME", + "LC_ADDRESS", + "LC_TELEPHONE", + "LC_MEASUREMENT", + "LC_IDENTIFICATION", + "LC_COLLATE", + "LC_CTYPE", + "LC_MONETARY", + "LC_NUMERIC", + "LC_TIME", + "LC_MESSAGES", + "LC_ALL", + "LANG", + NULL + }; extern char** environ; char* term = getenv("TERM"); - char* lang = getenv("LANG"); // clean env - environ[0] = NULL; + environ = NULL; if (term != NULL) { @@ -227,7 +245,15 @@ void env_init(struct passwd* pwd) setenv("SHELL", pwd->pw_shell, 1); setenv("USER", pwd->pw_name, 1); setenv("LOGNAME", pwd->pw_name, 1); - setenv("LANG", lang, 1); + + char* locale_value; + for (int i = 0; locale_var_names[i] != NULL; i++) + { + if ((locale_value = getenv(locale_var_names[i])) != NULL) + { + setenv(locale_var_names[i], locale_value, 1); + } + } // Set PATH if specified in the configuration if (strlen(config.path))