From 38a7c2270b5fa94b6275de351c73a0fc74da4ec7 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 29 Sep 2023 12:56:43 -0700 Subject: [PATCH 1/2] os: we need to copy the old lang pointer before we unsetenv --- src/os/locale.zig | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/os/locale.zig b/src/os/locale.zig index 5f0a960bc..8a8e3293d 100644 --- a/src/os/locale.zig +++ b/src/os/locale.zig @@ -26,7 +26,7 @@ pub fn ensureLocale() void { // Set the locale to whatever is set in env vars. if (setlocale(LC_ALL, "")) |v| { - log.debug("setlocale result={s}", .{v}); + log.info("setlocale from env result={s}", .{v}); return; } @@ -34,19 +34,30 @@ pub fn ensureLocale() void { // invalid. Try to set it without the LANG var set to use the system // default. if (std.os.getenv("LANG")) |old_lang| { - _ = unsetenv("LANG"); - defer _ = setenv("LANG", old_lang.ptr, 1); + if (old_lang.len > 0) { + // The old_lang pointer can be invalidated by unsetenv so we need + // to make a copy. LANG should never be longer than 128 bytes. If + // it is, we just set it to "". + var buf: [128]u8 = undefined; + var fba = std.heap.FixedBufferAllocator.init(&buf); + const alloc = fba.allocator(); + const old_copy = alloc.dupeZ(u8, old_lang) catch ""; - if (setlocale(LC_ALL, "")) |v| { - log.debug("setlocale result={s}", .{v}); - return; + // Unset the lang and defer to reset the copy. + _ = unsetenv("LANG"); + defer _ = setenv("LANG", old_copy.ptr, 1); + + if (setlocale(LC_ALL, "")) |v| { + log.info("setlocale after unset lang result={s}", .{v}); + return; + } } } // Failure again... fallback to en_US.UTF-8 log.warn("setlocale failed with LANG and system default. Falling back to en_US.UTF-8", .{}); if (setlocale(LC_ALL, "en_US.UTF-8")) |v| { - log.debug("setlocale result={s}", .{v}); + log.info("setlocale default result={s}", .{v}); return; } else log.err("setlocale failed even with the fallback, uncertain results", .{}); } From d878d16779f41dd84741bc40c642f271349cd034 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 29 Sep 2023 13:11:07 -0700 Subject: [PATCH 2/2] os: unset lang completely setlocale fails --- src/os/locale.zig | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/os/locale.zig b/src/os/locale.zig index 8a8e3293d..09d92b029 100644 --- a/src/os/locale.zig +++ b/src/os/locale.zig @@ -35,17 +35,10 @@ pub fn ensureLocale() void { // default. if (std.os.getenv("LANG")) |old_lang| { if (old_lang.len > 0) { - // The old_lang pointer can be invalidated by unsetenv so we need - // to make a copy. LANG should never be longer than 128 bytes. If - // it is, we just set it to "". - var buf: [128]u8 = undefined; - var fba = std.heap.FixedBufferAllocator.init(&buf); - const alloc = fba.allocator(); - const old_copy = alloc.dupeZ(u8, old_lang) catch ""; - - // Unset the lang and defer to reset the copy. + // We don't need to do both of these things but we do them + // both to be sure that lang is either empty or unset completely. + _ = setenv("LANG", "", 1); _ = unsetenv("LANG"); - defer _ = setenv("LANG", old_copy.ptr, 1); if (setlocale(LC_ALL, "")) |v| { log.info("setlocale after unset lang result={s}", .{v});