[libc-commits] [libc] [libc][stdlib] Add EnvironmentManager (PR #195260)

Jeff Bailey via libc-commits libc-commits at lists.llvm.org
Wed May 6 00:30:12 PDT 2026


================
@@ -0,0 +1,179 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation of internal environment management utilities.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/environ_internal.h"
+#include "config/app.h"
+#include "src/__support/CPP/new.h"
+#include "src/__support/CPP/string_view.h"
+#include "src/__support/alloc-checker.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+// Minimum initial capacity for the environment array when first allocated.
+// This avoids frequent reallocations for small environments.
+constexpr size_t MIN_ENVIRON_CAPACITY = 32;
+
+// Growth factor for environment array capacity when expanding.
+// When capacity is exceeded, new_capacity = old_capacity *
+// ENVIRON_GROWTH_FACTOR.
+constexpr size_t ENVIRON_GROWTH_FACTOR = 2;
+
+void EnvironmentManager::init_once() {
+  if (initialized)
+    return;
+
+  // Count entries in the startup environ.
+  char **env_ptr = reinterpret_cast<char **>(app.env_ptr);
+  if (env_ptr) {
+    size_t c = 0;
+    for (char **env = env_ptr; *env != nullptr; env++)
+      c++;
+    count = c;
+  }
+
+  initialized = true;
+}
+
+EnvironmentManager &EnvironmentManager::get_instance() {
+  static EnvironmentManager mgr;
+  mgr.init_once();
+  return mgr;
+}
+
+char **EnvironmentManager::get_array() {
+  if (is_ours)
+    return storage;
+  return reinterpret_cast<char **>(app.env_ptr);
+}
+
+EnvironmentManager::iterator EnvironmentManager::begin() { return get_array(); }
+
+EnvironmentManager::iterator EnvironmentManager::end() {
+  return get_array() + count;
+}
+
+size_t EnvironmentManager::size() const { return count; }
+
+char *EnvironmentManager::get(cpp::string_view name) {
+  cpp::optional<size_t> idx = find_var(name);
+  if (!idx)
+    return nullptr;
+  return get_array()[*idx] + name.size() + 1;
+}
+
+cpp::optional<size_t> EnvironmentManager::find_var(cpp::string_view name) {
+  char **env_array = get_array();
+  if (!env_array)
+    return cpp::nullopt;
+
+  for (size_t i = 0; i < count; i++) {
+    cpp::string_view current(env_array[i]);
----------------
kaladron wrote:

https://github.com/llvm/llvm-project/issues/196016

https://github.com/llvm/llvm-project/pull/195260


More information about the libc-commits mailing list