Raman Tenneti f2a7f83595 Introduce getenv to LLVM libc
Add support for getenv as defined by the Open Group's "System Interface &
 Header" in https://pubs.opengroup.org/onlinepubs/7908799/xsh/getenv.html

getenv requires a standard way of accessing the environment,
so a pointer to the environment is added to the startup in crt1.
Consquently, this function is not usable on top of other libcs.

Added starts_with method to StringView. getenv function uses it.

Co-authored-by: Jeff Bailey <jeffbailey@google.com>

Reviewed By: sivachandra, rtenneti

Differential Revision: https://reviews.llvm.org/D119403
2022-02-14 10:10:13 -08:00

43 lines
1.2 KiB
C++

//===-- Implementation of getenv ------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "src/stdlib/getenv.h"
#include "config/linux/app.h"
#include "src/__support/CPP/StringView.h"
#include "src/__support/common.h"
#include <stddef.h> // For size_t.
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(char *, getenv, (const char *name)) {
char **env_ptr = reinterpret_cast<char **>(__llvm_libc::app.envPtr);
if (name == nullptr || env_ptr == nullptr)
return nullptr;
__llvm_libc::cpp::StringView env_var_name(name);
if (env_var_name.size() == 0)
return nullptr;
for (char **env = env_ptr; *env != nullptr; env++) {
__llvm_libc::cpp::StringView cur(*env);
if (!cur.starts_with(env_var_name))
continue;
if (cur[env_var_name.size()] != '=')
continue;
return const_cast<char *>(
cur.remove_prefix(env_var_name.size() + 1).data());
}
return nullptr;
}
} // namespace __llvm_libc