From da143b99403fd526e61f080dcc27aed88b97a914 Mon Sep 17 00:00:00 2001 From: Vladislav Sayapin <70110788+v-sayapin@users.noreply.github.com> Date: Mon, 5 Jan 2026 16:12:05 +0300 Subject: [PATCH] server : fix router child env in containerized environments (#18562) --- tools/server/server-models.cpp | 52 ++++++++++++++++++++++++++++++---- tools/server/server-models.h | 6 ++-- tools/server/server.cpp | 4 +-- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/tools/server/server-models.cpp b/tools/server/server-models.cpp index 56e1dc46b8..803cb02e6e 100644 --- a/tools/server/server-models.cpp +++ b/tools/server/server-models.cpp @@ -21,11 +21,13 @@ #ifdef _WIN32 #include +#include #else #include #include #include #include +extern char **environ; #endif #if defined(__APPLE__) && defined(__MACH__) @@ -99,6 +101,49 @@ static void unset_reserved_args(common_preset & preset, bool unset_model_args) { } } +#ifdef _WIN32 +static std::string wide_to_utf8(const wchar_t * ws) { + if (!ws || !*ws) { + return {}; + } + + const int len = static_cast(std::wcslen(ws)); + const int bytes = WideCharToMultiByte(CP_UTF8, 0, ws, len, nullptr, 0, nullptr, nullptr); + if (bytes == 0) { + return {}; + } + + std::string utf8(bytes, '\0'); + WideCharToMultiByte(CP_UTF8, 0, ws, len, utf8.data(), bytes, nullptr, nullptr); + + return utf8; +} +#endif + +static std::vector get_environment() { + std::vector env; + +#ifdef _WIN32 + LPWCH env_block = GetEnvironmentStringsW(); + if (!env_block) { + return env; + } + for (LPWCH e = env_block; *e; e += wcslen(e) + 1) { + env.emplace_back(wide_to_utf8(e)); + } + FreeEnvironmentStringsW(env_block); +#else + if (environ == nullptr) { + return env; + } + for (char ** e = environ; *e != nullptr; e++) { + env.emplace_back(*e); + } +#endif + + return env; +} + void server_model_meta::update_args(common_preset_context & ctx_preset, std::string bin_path) { // update params unset_reserved_args(preset, false); @@ -117,14 +162,11 @@ void server_model_meta::update_args(common_preset_context & ctx_preset, std::str server_models::server_models( const common_params & params, int argc, - char ** argv, - char ** envp) + char ** argv) : ctx_preset(LLAMA_EXAMPLE_SERVER), base_params(params), + base_env(get_environment()), base_preset(ctx_preset.load_from_args(argc, argv)) { - for (char ** env = envp; *env != nullptr; env++) { - base_env.push_back(std::string(*env)); - } // clean up base preset unset_reserved_args(base_preset, true); // set binary path diff --git a/tools/server/server-models.h b/tools/server/server-models.h index 24ddc65662..a397abda4a 100644 --- a/tools/server/server-models.h +++ b/tools/server/server-models.h @@ -105,7 +105,7 @@ private: void add_model(server_model_meta && meta); public: - server_models(const common_params & params, int argc, char ** argv, char ** envp); + server_models(const common_params & params, int argc, char ** argv); void load_models(); @@ -147,8 +147,8 @@ struct server_models_routes { common_params params; json webui_settings = json::object(); server_models models; - server_models_routes(const common_params & params, int argc, char ** argv, char ** envp) - : params(params), models(params, argc, argv, envp) { + server_models_routes(const common_params & params, int argc, char ** argv) + : params(params), models(params, argc, argv) { if (!this->params.webui_config_json.empty()) { try { webui_settings = json::parse(this->params.webui_config_json); diff --git a/tools/server/server.cpp b/tools/server/server.cpp index 0fbc7b6d35..1d9abf6055 100644 --- a/tools/server/server.cpp +++ b/tools/server/server.cpp @@ -66,7 +66,7 @@ static server_http_context::handler_t ex_wrapper(server_http_context::handler_t }; } -int main(int argc, char ** argv, char ** envp) { +int main(int argc, char ** argv) { // own arguments required by this example common_params params; @@ -126,7 +126,7 @@ int main(int argc, char ** argv, char ** envp) { if (is_router_server) { // setup server instances manager try { - models_routes.emplace(params, argc, argv, envp); + models_routes.emplace(params, argc, argv); } catch (const std::exception & e) { LOG_ERR("%s: failed to initialize router models: %s\n", __func__, e.what()); return 1;