Path: blob/main/contrib/llvm-project/lldb/source/Host/posix/HostInfoPosix.cpp
39608 views
//===-- HostInfoPosix.cpp -------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Host/posix/HostInfoPosix.h"9#include "lldb/Utility/Log.h"10#include "lldb/Utility/UserIDResolver.h"1112#include "llvm/ADT/SmallString.h"13#include "llvm/ADT/Twine.h"14#include "llvm/Support/Path.h"15#include "llvm/Support/raw_ostream.h"1617#include <climits>18#include <cstdlib>19#include <grp.h>20#include <mutex>21#include <optional>22#include <pwd.h>23#include <sys/types.h>24#include <sys/utsname.h>25#include <unistd.h>2627using namespace lldb_private;2829size_t HostInfoPosix::GetPageSize() { return ::getpagesize(); }3031bool HostInfoPosix::GetHostname(std::string &s) {32char hostname[PATH_MAX];33hostname[sizeof(hostname) - 1] = '\0';34if (::gethostname(hostname, sizeof(hostname) - 1) == 0) {35s.assign(hostname);36return true;37}38return false;39}4041std::optional<std::string> HostInfoPosix::GetOSKernelDescription() {42struct utsname un;43if (uname(&un) < 0)44return std::nullopt;4546return std::string(un.version);47}4849#ifdef __ANDROID__50#include <android/api-level.h>51#endif52#if defined(__ANDROID_API__) && __ANDROID_API__ < 2153#define USE_GETPWUID54#endif5556namespace {57class PosixUserIDResolver : public UserIDResolver {58protected:59std::optional<std::string> DoGetUserName(id_t uid) override;60std::optional<std::string> DoGetGroupName(id_t gid) override;61};62} // namespace6364struct PasswdEntry {65std::string username;66std::string shell;67};6869static std::optional<PasswdEntry> GetPassword(id_t uid) {70#ifdef USE_GETPWUID71// getpwuid_r is missing from android-972// The caller should provide some thread safety by making sure no one calls73// this function concurrently, because using getpwuid is ultimately not74// thread-safe as we don't know who else might be calling it.75if (auto *user_info_ptr = ::getpwuid(uid))76return PasswdEntry{user_info_ptr->pw_name, user_info_ptr->pw_shell};77#else78struct passwd user_info;79struct passwd *user_info_ptr = &user_info;80char user_buffer[PATH_MAX];81size_t user_buffer_size = sizeof(user_buffer);82if (::getpwuid_r(uid, &user_info, user_buffer, user_buffer_size,83&user_info_ptr) == 0 &&84user_info_ptr) {85return PasswdEntry{user_info_ptr->pw_name, user_info_ptr->pw_shell};86}87#endif88return std::nullopt;89}9091std::optional<std::string> PosixUserIDResolver::DoGetUserName(id_t uid) {92if (std::optional<PasswdEntry> password = GetPassword(uid))93return password->username;94return std::nullopt;95}9697std::optional<std::string> PosixUserIDResolver::DoGetGroupName(id_t gid) {98#ifndef __ANDROID__99char group_buffer[PATH_MAX];100size_t group_buffer_size = sizeof(group_buffer);101struct group group_info;102struct group *group_info_ptr = &group_info;103// Try the threadsafe version first104if (::getgrgid_r(gid, &group_info, group_buffer, group_buffer_size,105&group_info_ptr) == 0) {106if (group_info_ptr)107return std::string(group_info_ptr->gr_name);108} else {109// The threadsafe version isn't currently working for me on darwin, but the110// non-threadsafe version is, so I am calling it below.111group_info_ptr = ::getgrgid(gid);112if (group_info_ptr)113return std::string(group_info_ptr->gr_name);114}115#endif116return std::nullopt;117}118119static llvm::ManagedStatic<PosixUserIDResolver> g_user_id_resolver;120121UserIDResolver &HostInfoPosix::GetUserIDResolver() {122return *g_user_id_resolver;123}124125uint32_t HostInfoPosix::GetUserID() { return getuid(); }126127uint32_t HostInfoPosix::GetGroupID() { return getgid(); }128129uint32_t HostInfoPosix::GetEffectiveUserID() { return geteuid(); }130131uint32_t HostInfoPosix::GetEffectiveGroupID() { return getegid(); }132133FileSpec HostInfoPosix::GetDefaultShell() {134if (const char *v = ::getenv("SHELL"))135return FileSpec(v);136if (std::optional<PasswdEntry> password = GetPassword(::geteuid()))137return FileSpec(password->shell);138return FileSpec("/bin/sh");139}140141bool HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec) {142return ComputePathRelativeToLibrary(file_spec, "/bin");143}144145bool HostInfoPosix::ComputeHeaderDirectory(FileSpec &file_spec) {146FileSpec temp_file("/opt/local/include/lldb");147file_spec.SetDirectory(temp_file.GetPath());148return true;149}150151bool HostInfoPosix::GetEnvironmentVar(const std::string &var_name,152std::string &var) {153if (const char *pvar = ::getenv(var_name.c_str())) {154var = std::string(pvar);155return true;156}157return false;158}159160161