diff options
Diffstat (limited to 'source/Host/posix/HostInfoPosix.cpp')
-rw-r--r-- | source/Host/posix/HostInfoPosix.cpp | 104 |
1 files changed, 33 insertions, 71 deletions
diff --git a/source/Host/posix/HostInfoPosix.cpp b/source/Host/posix/HostInfoPosix.cpp index 4763ebc9b9d4..f300e22e9e5c 100644 --- a/source/Host/posix/HostInfoPosix.cpp +++ b/source/Host/posix/HostInfoPosix.cpp @@ -1,13 +1,13 @@ //===-- HostInfoPosix.cpp ---------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "lldb/Host/posix/HostInfoPosix.h" +#include "lldb/Utility/UserIDResolver.h" #include "lldb/Utility/Log.h" #include "llvm/ADT/SmallString.h" @@ -49,40 +49,38 @@ bool HostInfoPosix::GetHostname(std::string &s) { #define USE_GETPWUID #endif -#ifdef USE_GETPWUID -static std::mutex s_getpwuid_lock; -#endif +namespace { +class PosixUserIDResolver : public UserIDResolver { +protected: + llvm::Optional<std::string> DoGetUserName(id_t uid) override; + llvm::Optional<std::string> DoGetGroupName(id_t gid) override; +}; +} // namespace -const char *HostInfoPosix::LookupUserName(uint32_t uid, - std::string &user_name) { +llvm::Optional<std::string> PosixUserIDResolver::DoGetUserName(id_t uid) { #ifdef USE_GETPWUID // getpwuid_r is missing from android-9 - // make getpwuid thread safe with a mutex - std::lock_guard<std::mutex> lock(s_getpwuid_lock); + // UserIDResolver provides some thread safety by making sure noone calls this + // function concurrently, but using getpwuid is ultimately not thread-safe as + // we don't know who else might be calling it. struct passwd *user_info_ptr = ::getpwuid(uid); - if (user_info_ptr) { - user_name.assign(user_info_ptr->pw_name); - return user_name.c_str(); - } + if (user_info_ptr) + return std::string(user_info_ptr->pw_name); #else struct passwd user_info; struct passwd *user_info_ptr = &user_info; char user_buffer[PATH_MAX]; size_t user_buffer_size = sizeof(user_buffer); if (::getpwuid_r(uid, &user_info, user_buffer, user_buffer_size, - &user_info_ptr) == 0) { - if (user_info_ptr) { - user_name.assign(user_info_ptr->pw_name); - return user_name.c_str(); - } + &user_info_ptr) == 0 && + user_info_ptr) { + return std::string(user_info_ptr->pw_name); } #endif - user_name.clear(); - return nullptr; + return llvm::None; } -const char *HostInfoPosix::LookupGroupName(uint32_t gid, - std::string &group_name) { +llvm::Optional<std::string> PosixUserIDResolver::DoGetGroupName(id_t gid) { #ifndef __ANDROID__ char group_buffer[PATH_MAX]; size_t group_buffer_size = sizeof(group_buffer); @@ -91,24 +89,25 @@ const char *HostInfoPosix::LookupGroupName(uint32_t gid, // Try the threadsafe version first if (::getgrgid_r(gid, &group_info, group_buffer, group_buffer_size, &group_info_ptr) == 0) { - if (group_info_ptr) { - group_name.assign(group_info_ptr->gr_name); - return group_name.c_str(); - } + if (group_info_ptr) + return std::string(group_info_ptr->gr_name); } else { // The threadsafe version isn't currently working for me on darwin, but the // non-threadsafe version is, so I am calling it below. group_info_ptr = ::getgrgid(gid); - if (group_info_ptr) { - group_name.assign(group_info_ptr->gr_name); - return group_name.c_str(); - } + if (group_info_ptr) + return std::string(group_info_ptr->gr_name); } - group_name.clear(); #else assert(false && "getgrgid_r() not supported on Android"); #endif - return NULL; + return llvm::None; +} + +static llvm::ManagedStatic<PosixUserIDResolver> g_user_id_resolver; + +UserIDResolver &HostInfoPosix::GetUserIDResolver() { + return *g_user_id_resolver; } uint32_t HostInfoPosix::GetUserID() { return getuid(); } @@ -121,43 +120,6 @@ uint32_t HostInfoPosix::GetEffectiveGroupID() { return getegid(); } FileSpec HostInfoPosix::GetDefaultShell() { return FileSpec("/bin/sh"); } -bool HostInfoPosix::ComputePathRelativeToLibrary(FileSpec &file_spec, - llvm::StringRef dir) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - - FileSpec lldb_file_spec = GetShlibDir(); - if (!lldb_file_spec) - return false; - - std::string raw_path = lldb_file_spec.GetPath(); - // drop library directory - llvm::StringRef parent_path = llvm::sys::path::parent_path(raw_path); - - // Most Posix systems (e.g. Linux/*BSD) will attempt to replace a */lib with - // */bin as the base directory for helper exe programs. This will fail if - // the /lib and /bin directories are rooted in entirely different trees. - if (log) - log->Printf("HostInfoPosix::ComputePathRelativeToLibrary() attempting to " - "derive the %s path from this path: %s", - dir.data(), raw_path.c_str()); - - if (!parent_path.empty()) { - // Now write in bin in place of lib. - raw_path = (parent_path + dir).str(); - - if (log) - log->Printf("Host::%s() derived the bin path as: %s", __FUNCTION__, - raw_path.c_str()); - } else { - if (log) - log->Printf("Host::%s() failed to find /lib/liblldb within the shared " - "lib path, bailing on bin path construction", - __FUNCTION__); - } - file_spec.GetDirectory().SetString(raw_path); - return (bool)file_spec.GetDirectory(); -} - bool HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec) { return ComputePathRelativeToLibrary(file_spec, "/bin"); } |