77// ===----------------------------------------------------------------------===//
88
99#include " lldb/Host/posix/HostInfoPosix.h"
10+ #include " lldb/Host/Config.h"
11+ #include " lldb/Host/FileSystem.h"
12+ #include " lldb/Host/HostInfo.h"
1013#include " lldb/Utility/Log.h"
1114#include " lldb/Utility/UserIDResolver.h"
12-
1315#include " llvm/ADT/SmallString.h"
1416#include " llvm/ADT/Twine.h"
1517#include " llvm/Support/Path.h"
1618#include " llvm/Support/raw_ostream.h"
1719
1820#include < climits>
21+ #include < cstdio>
1922#include < cstdlib>
23+ #include < cstring>
2024#include < grp.h>
2125#include < mutex>
2226#include < optional>
2731
2832using namespace lldb_private ;
2933
34+ namespace {
35+ struct HostInfoPosixFields {
36+ llvm::once_flag m_os_version_once_flag;
37+ llvm::VersionTuple m_os_version;
38+ };
39+ } // namespace
40+
41+ llvm::VersionTuple HostInfoPosix::GetOSVersion () {
42+ static HostInfoPosixFields *g_fields = new HostInfoPosixFields ();
43+ assert (g_fields && " Missing call to Initialize?" );
44+ llvm::call_once (g_fields->m_os_version_once_flag , []() {
45+ struct utsname un;
46+ if (uname (&un) != 0 )
47+ return ;
48+
49+ llvm::StringRef release = un.release ;
50+ // The Linux kernel release string can include a lot of stuff (e.g.
51+ // 4.9.0-6-amd64). We're only interested in the numbered prefix.
52+ release = release.substr (0 , release.find_first_not_of (" 0123456789." ));
53+ g_fields->m_os_version .tryParse (release);
54+ });
55+
56+ return g_fields->m_os_version ;
57+ }
58+
3059size_t HostInfoPosix::GetPageSize () { return ::getpagesize (); }
3160
3261bool HostInfoPosix::GetHostname (std::string &s) {
@@ -47,6 +76,16 @@ std::optional<std::string> HostInfoPosix::GetOSKernelDescription() {
4776 return std::string (un.version );
4877}
4978
79+ std::optional<std::string> HostInfoPosix::GetOSBuildString () {
80+ struct utsname un;
81+ ::memset (&un, 0 , sizeof (utsname));
82+
83+ if (uname (&un) < 0 )
84+ return std::nullopt ;
85+
86+ return std::string (un.release );
87+ }
88+
5089#ifdef __ANDROID__
5190#include < android/api-level.h>
5291#endif
@@ -140,7 +179,32 @@ FileSpec HostInfoPosix::GetDefaultShell() {
140179}
141180
142181bool HostInfoPosix::ComputeSupportExeDirectory (FileSpec &file_spec) {
143- return ComputePathRelativeToLibrary (file_spec, " /bin" );
182+ if (ComputePathRelativeToLibrary (file_spec, " /bin" ) &&
183+ file_spec.IsAbsolute () && FileSystem::Instance ().Exists (file_spec))
184+ return true ;
185+ file_spec.SetDirectory (HostInfo::GetProgramFileSpec ().GetDirectory ());
186+ return !file_spec.GetDirectory ().IsEmpty ();
187+ }
188+
189+ bool HostInfoPosix::ComputeSystemPluginsDirectory (FileSpec &file_spec) {
190+ FileSpec temp_file (" /usr/" LLDB_INSTALL_LIBDIR_BASENAME " /lldb/plugins" );
191+ FileSystem::Instance ().Resolve (temp_file);
192+ file_spec.SetDirectory (temp_file.GetPath ());
193+ return true ;
194+ }
195+
196+ bool HostInfoPosix::ComputeUserPluginsDirectory (FileSpec &file_spec) {
197+ // XDG Base Directory Specification
198+ // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html If
199+ // XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb.
200+ const char *xdg_data_home = getenv (" XDG_DATA_HOME" );
201+ if (xdg_data_home && xdg_data_home[0 ]) {
202+ std::string user_plugin_dir (xdg_data_home);
203+ user_plugin_dir += " /lldb" ;
204+ file_spec.SetDirectory (user_plugin_dir.c_str ());
205+ } else
206+ file_spec.SetDirectory (" ~/.local/share/lldb" );
207+ return true ;
144208}
145209
146210bool HostInfoPosix::ComputeHeaderDirectory (FileSpec &file_spec) {
0 commit comments