Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
init: set locale after importing full environment (re: c692ee1)
The previous commit introduced a mysterious regression test failure on the GitHub CI runner (and nowhere else that I could find) while running the regression tests in the nl_NL.UTF-8 locale: test libcmd(nl_NL.UTF-8) begins at 2024-12-26+07:51:49 libcmd.sh[856]: FAIL: PATH_LEADING_SLASHES handling (expected $'/\n//\n//\n//\n//\n//server\n//server', got $'/\n/\n/\n/\n/\n/server\n/server') test libcmd(nl_NL.UTF-8) failed at 2024-12-26+07:51:50 with exit code 1 [ 142 tests 1 error ] Analysis: It seems impossible for the problem to be in the leading slashes handling code, so the only possibility left is that the _AST_FEATURES export (to cause 'getconf PATH_LEADING_SLASHES' to return 1) in libcmd.sh:854 did not take effect. _AST_FEATURES is read once, on the first call to astconf and related functions. See the INITIALIZE macro in astconf.c. After many hours of experimenting I found that, in the OS/config/ locale combination on the GitHub CI runner, importing locale variables from the environment via env_init() in init.c may, very indirectly, trigger a call to astconf before the environment is fully imported. This will then potentially check for _AST_FEATURES before it is imported, and it won't check again after that. The relevant part of the call stack for this situation is: 12 astconf -- called in pathbin because getenv("PATH") returned NULL, indicating environment is not fully imported, thus also causing _AST_FEATURES to fail to be honoured 11 pathbin (pathbin.c:37) 10 pathpath_20100601 (pathpath.c:128) 09 pathpath (pathpath.c:40) 08 mcfind (mc.c:185) 07 single (setlocale.c:2394) 06 _ast_setlocale (setlocale.c:480; macro at ast_std.h:138) 05 put_lang (init.c:480) 04 nv_putv (nvdisc.c:144) 03 nv_putval (name.c:1645) 02 nv_open (name.c:1511) 01 env_init (init.c:1913) So, long story short, since setting the locale via _ast_setlocale may require a fully imported environment, we must implement a way to stop the put_lang discipline function from calling setlocale while env_init is importing variables like LANG, LC_ALL, etc, and defer these calls until after the environment is fully imported. src/cmd/ksh93/include/shell.h: - We can use a new state flag for this. The SH_PREINIT state bit is unused as of 921bbca. Replace it with a new SH_LCINIT state bit. src/cmd/ksh93/sh/init.c: - put_lang: While the SH_INIT flag is on (we're initialising the shell) but not SH_LCINIT, defer the put_lang action by storing the parameters of the put_lang calls in a linked list. - env_init: After completing the loop that imports all the env vars, walk through the created linked list and execute all the deferred put_lang calls with SH_LCINIT set. Now, _ast_setlocale will be called with the full environment available.
- Loading branch information