|
103 | 103 | #include <grp.h> |
104 | 104 | #include <sys/types.h> |
105 | 105 | #include <sys/stat.h> |
| 106 | +#include <locale.h> |
106 | 107 |
|
107 | 108 | #ifdef __linux__ |
108 | 109 | #include <sys/prctl.h> |
@@ -932,11 +933,34 @@ static int is_all_digits(const char *s) { |
932 | 933 | return 1; |
933 | 934 | } |
934 | 935 |
|
| 936 | +/* Try C.UTF-8 → en_US.UTF-8 → C, and keep env consistent. */ |
| 937 | +static void set_locale_utf8_best_effort(void) { |
| 938 | + /* Try C.UTF-8 first (works on modern glibc & musl/Alpine) */ |
| 939 | + if (setlocale(LC_CTYPE, "C.UTF-8")) { |
| 940 | + setenv("LANG", "C.UTF-8", 1); |
| 941 | + setenv("LC_CTYPE", "C.UTF-8", 1); |
| 942 | + setenv("CHARSET", "UTF-8", 1); /* helps BusyBox wget */ |
| 943 | + return; |
| 944 | + } |
| 945 | + /* Fallback for older glibc (e.g., CentOS 7) */ |
| 946 | + if (setlocale(LC_CTYPE, "en_US.UTF-8")) { |
| 947 | + setenv("LANG", "en_US.UTF-8", 1); |
| 948 | + setenv("LC_CTYPE", "en_US.UTF-8", 1); |
| 949 | + setenv("CHARSET", "UTF-8", 1); |
| 950 | + return; |
| 951 | + } |
| 952 | + /* Last resort: plain C (ASCII). Still deterministic. */ |
| 953 | + setlocale(LC_CTYPE, "C"); |
| 954 | + setenv("LANG", "C", 1); |
| 955 | + setenv("LC_CTYPE", "C", 1); |
| 956 | + setenv("CHARSET", "ASCII", 1); |
| 957 | +} |
| 958 | + |
935 | 959 | // Sanitize environment & process state early |
936 | 960 | static void sanitize_process_early(void) { |
937 | 961 | clearenv_portable(); |
938 | 962 | setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/run/current-system/sw/bin", 1); |
939 | | - setenv("LANG", "C", 1); |
| 963 | + set_locale_utf8_best_effort(); |
940 | 964 | umask(077); |
941 | 965 | #ifdef __linux__ |
942 | 966 | (void)prctl(PR_SET_DUMPABLE, 0, 0, 0, 0); |
|
0 commit comments