]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/API/SBPlatform.cpp
Partial MFV r329753:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / API / SBPlatform.cpp
1 //===-- SBPlatform.cpp ------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/API/SBPlatform.h"
11 #include "lldb/API/SBError.h"
12 #include "lldb/API/SBFileSpec.h"
13 #include "lldb/API/SBLaunchInfo.h"
14 #include "lldb/API/SBUnixSignals.h"
15 #include "lldb/Host/File.h"
16 #include "lldb/Interpreter/Args.h"
17 #include "lldb/Target/Platform.h"
18 #include "lldb/Target/Target.h"
19 #include "lldb/Utility/ArchSpec.h"
20 #include "lldb/Utility/Status.h"
21
22 #include "llvm/Support/FileSystem.h"
23
24 #include <functional>
25
26 using namespace lldb;
27 using namespace lldb_private;
28
29 //----------------------------------------------------------------------
30 // PlatformConnectOptions
31 //----------------------------------------------------------------------
32 struct PlatformConnectOptions {
33   PlatformConnectOptions(const char *url = NULL)
34       : m_url(), m_rsync_options(), m_rsync_remote_path_prefix(),
35         m_rsync_enabled(false), m_rsync_omit_hostname_from_remote_path(false),
36         m_local_cache_directory() {
37     if (url && url[0])
38       m_url = url;
39   }
40
41   ~PlatformConnectOptions() {}
42
43   std::string m_url;
44   std::string m_rsync_options;
45   std::string m_rsync_remote_path_prefix;
46   bool m_rsync_enabled;
47   bool m_rsync_omit_hostname_from_remote_path;
48   ConstString m_local_cache_directory;
49 };
50
51 //----------------------------------------------------------------------
52 // PlatformShellCommand
53 //----------------------------------------------------------------------
54 struct PlatformShellCommand {
55   PlatformShellCommand(const char *shell_command = NULL)
56       : m_command(), m_working_dir(), m_status(0), m_signo(0),
57         m_timeout_sec(UINT32_MAX) {
58     if (shell_command && shell_command[0])
59       m_command = shell_command;
60   }
61
62   ~PlatformShellCommand() {}
63
64   std::string m_command;
65   std::string m_working_dir;
66   std::string m_output;
67   int m_status;
68   int m_signo;
69   uint32_t m_timeout_sec;
70 };
71 //----------------------------------------------------------------------
72 // SBPlatformConnectOptions
73 //----------------------------------------------------------------------
74 SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)
75     : m_opaque_ptr(new PlatformConnectOptions(url)) {}
76
77 SBPlatformConnectOptions::SBPlatformConnectOptions(
78     const SBPlatformConnectOptions &rhs)
79     : m_opaque_ptr(new PlatformConnectOptions()) {
80   *m_opaque_ptr = *rhs.m_opaque_ptr;
81 }
82
83 SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }
84
85 void SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
86   *m_opaque_ptr = *rhs.m_opaque_ptr;
87 }
88
89 const char *SBPlatformConnectOptions::GetURL() {
90   if (m_opaque_ptr->m_url.empty())
91     return NULL;
92   return m_opaque_ptr->m_url.c_str();
93 }
94
95 void SBPlatformConnectOptions::SetURL(const char *url) {
96   if (url && url[0])
97     m_opaque_ptr->m_url = url;
98   else
99     m_opaque_ptr->m_url.clear();
100 }
101
102 bool SBPlatformConnectOptions::GetRsyncEnabled() {
103   return m_opaque_ptr->m_rsync_enabled;
104 }
105
106 void SBPlatformConnectOptions::EnableRsync(
107     const char *options, const char *remote_path_prefix,
108     bool omit_hostname_from_remote_path) {
109   m_opaque_ptr->m_rsync_enabled = true;
110   m_opaque_ptr->m_rsync_omit_hostname_from_remote_path =
111       omit_hostname_from_remote_path;
112   if (remote_path_prefix && remote_path_prefix[0])
113     m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;
114   else
115     m_opaque_ptr->m_rsync_remote_path_prefix.clear();
116
117   if (options && options[0])
118     m_opaque_ptr->m_rsync_options = options;
119   else
120     m_opaque_ptr->m_rsync_options.clear();
121 }
122
123 void SBPlatformConnectOptions::DisableRsync() {
124   m_opaque_ptr->m_rsync_enabled = false;
125 }
126
127 const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {
128   return m_opaque_ptr->m_local_cache_directory.GetCString();
129 }
130
131 void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) {
132   if (path && path[0])
133     m_opaque_ptr->m_local_cache_directory.SetCString(path);
134   else
135     m_opaque_ptr->m_local_cache_directory = ConstString();
136 }
137
138 //----------------------------------------------------------------------
139 // SBPlatformShellCommand
140 //----------------------------------------------------------------------
141 SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
142     : m_opaque_ptr(new PlatformShellCommand(shell_command)) {}
143
144 SBPlatformShellCommand::SBPlatformShellCommand(
145     const SBPlatformShellCommand &rhs)
146     : m_opaque_ptr(new PlatformShellCommand()) {
147   *m_opaque_ptr = *rhs.m_opaque_ptr;
148 }
149
150 SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; }
151
152 void SBPlatformShellCommand::Clear() {
153   m_opaque_ptr->m_output = std::string();
154   m_opaque_ptr->m_status = 0;
155   m_opaque_ptr->m_signo = 0;
156 }
157
158 const char *SBPlatformShellCommand::GetCommand() {
159   if (m_opaque_ptr->m_command.empty())
160     return NULL;
161   return m_opaque_ptr->m_command.c_str();
162 }
163
164 void SBPlatformShellCommand::SetCommand(const char *shell_command) {
165   if (shell_command && shell_command[0])
166     m_opaque_ptr->m_command = shell_command;
167   else
168     m_opaque_ptr->m_command.clear();
169 }
170
171 const char *SBPlatformShellCommand::GetWorkingDirectory() {
172   if (m_opaque_ptr->m_working_dir.empty())
173     return NULL;
174   return m_opaque_ptr->m_working_dir.c_str();
175 }
176
177 void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
178   if (path && path[0])
179     m_opaque_ptr->m_working_dir = path;
180   else
181     m_opaque_ptr->m_working_dir.clear();
182 }
183
184 uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
185   return m_opaque_ptr->m_timeout_sec;
186 }
187
188 void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
189   m_opaque_ptr->m_timeout_sec = sec;
190 }
191
192 int SBPlatformShellCommand::GetSignal() { return m_opaque_ptr->m_signo; }
193
194 int SBPlatformShellCommand::GetStatus() { return m_opaque_ptr->m_status; }
195
196 const char *SBPlatformShellCommand::GetOutput() {
197   if (m_opaque_ptr->m_output.empty())
198     return NULL;
199   return m_opaque_ptr->m_output.c_str();
200 }
201
202 //----------------------------------------------------------------------
203 // SBPlatform
204 //----------------------------------------------------------------------
205 SBPlatform::SBPlatform() : m_opaque_sp() {}
206
207 SBPlatform::SBPlatform(const char *platform_name) : m_opaque_sp() {
208   Status error;
209   if (platform_name && platform_name[0])
210     m_opaque_sp = Platform::Create(ConstString(platform_name), error);
211 }
212
213 SBPlatform::~SBPlatform() {}
214
215 bool SBPlatform::IsValid() const { return m_opaque_sp.get() != NULL; }
216
217 void SBPlatform::Clear() { m_opaque_sp.reset(); }
218
219 const char *SBPlatform::GetName() {
220   PlatformSP platform_sp(GetSP());
221   if (platform_sp)
222     return platform_sp->GetName().GetCString();
223   return NULL;
224 }
225
226 lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }
227
228 void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {
229   m_opaque_sp = platform_sp;
230 }
231
232 const char *SBPlatform::GetWorkingDirectory() {
233   PlatformSP platform_sp(GetSP());
234   if (platform_sp)
235     return platform_sp->GetWorkingDirectory().GetCString();
236   return NULL;
237 }
238
239 bool SBPlatform::SetWorkingDirectory(const char *path) {
240   PlatformSP platform_sp(GetSP());
241   if (platform_sp) {
242     if (path)
243       platform_sp->SetWorkingDirectory(FileSpec{path, false});
244     else
245       platform_sp->SetWorkingDirectory(FileSpec{});
246     return true;
247   }
248   return false;
249 }
250
251 SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) {
252   SBError sb_error;
253   PlatformSP platform_sp(GetSP());
254   if (platform_sp && connect_options.GetURL()) {
255     Args args;
256     args.AppendArgument(
257         llvm::StringRef::withNullAsEmpty(connect_options.GetURL()));
258     sb_error.ref() = platform_sp->ConnectRemote(args);
259   } else {
260     sb_error.SetErrorString("invalid platform");
261   }
262   return sb_error;
263 }
264
265 void SBPlatform::DisconnectRemote() {
266   PlatformSP platform_sp(GetSP());
267   if (platform_sp)
268     platform_sp->DisconnectRemote();
269 }
270
271 bool SBPlatform::IsConnected() {
272   PlatformSP platform_sp(GetSP());
273   if (platform_sp)
274     platform_sp->IsConnected();
275   return false;
276 }
277
278 const char *SBPlatform::GetTriple() {
279   PlatformSP platform_sp(GetSP());
280   if (platform_sp) {
281     ArchSpec arch(platform_sp->GetSystemArchitecture());
282     if (arch.IsValid()) {
283       // Const-ify the string so we don't need to worry about the lifetime of
284       // the string
285       return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
286     }
287   }
288   return NULL;
289 }
290
291 const char *SBPlatform::GetOSBuild() {
292   PlatformSP platform_sp(GetSP());
293   if (platform_sp) {
294     std::string s;
295     if (platform_sp->GetOSBuildString(s)) {
296       if (!s.empty()) {
297         // Const-ify the string so we don't need to worry about the lifetime of
298         // the string
299         return ConstString(s.c_str()).GetCString();
300       }
301     }
302   }
303   return NULL;
304 }
305
306 const char *SBPlatform::GetOSDescription() {
307   PlatformSP platform_sp(GetSP());
308   if (platform_sp) {
309     std::string s;
310     if (platform_sp->GetOSKernelDescription(s)) {
311       if (!s.empty()) {
312         // Const-ify the string so we don't need to worry about the lifetime of
313         // the string
314         return ConstString(s.c_str()).GetCString();
315       }
316     }
317   }
318   return NULL;
319 }
320
321 const char *SBPlatform::GetHostname() {
322   PlatformSP platform_sp(GetSP());
323   if (platform_sp)
324     return platform_sp->GetHostname();
325   return NULL;
326 }
327
328 uint32_t SBPlatform::GetOSMajorVersion() {
329   uint32_t major, minor, update;
330   PlatformSP platform_sp(GetSP());
331   if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
332     return major;
333   return UINT32_MAX;
334 }
335
336 uint32_t SBPlatform::GetOSMinorVersion() {
337   uint32_t major, minor, update;
338   PlatformSP platform_sp(GetSP());
339   if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
340     return minor;
341   return UINT32_MAX;
342 }
343
344 uint32_t SBPlatform::GetOSUpdateVersion() {
345   uint32_t major, minor, update;
346   PlatformSP platform_sp(GetSP());
347   if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
348     return update;
349   return UINT32_MAX;
350 }
351
352 SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {
353   SBError sb_error;
354   PlatformSP platform_sp(GetSP());
355   if (platform_sp) {
356     sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
357   } else {
358     sb_error.SetErrorString("invalid platform");
359   }
360   return sb_error;
361 }
362
363 SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {
364   return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
365     if (src.Exists()) {
366       uint32_t permissions = src.ref().GetPermissions();
367       if (permissions == 0) {
368         if (llvm::sys::fs::is_directory(src.ref().GetPath()))
369           permissions = eFilePermissionsDirectoryDefault;
370         else
371           permissions = eFilePermissionsFileDefault;
372       }
373
374       return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
375     }
376
377     Status error;
378     error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
379                                    src.ref().GetPath().c_str());
380     return error;
381   });
382 }
383
384 SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
385   return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
386     if (src.Exists())
387       return platform_sp->Install(src.ref(), dst.ref());
388
389     Status error;
390     error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
391                                    src.ref().GetPath().c_str());
392     return error;
393   });
394 }
395
396 SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
397   return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
398     const char *command = shell_command.GetCommand();
399     if (!command)
400       return Status("invalid shell command (empty)");
401
402     const char *working_dir = shell_command.GetWorkingDirectory();
403     if (working_dir == NULL) {
404       working_dir = platform_sp->GetWorkingDirectory().GetCString();
405       if (working_dir)
406         shell_command.SetWorkingDirectory(working_dir);
407     }
408     return platform_sp->RunShellCommand(
409         command, FileSpec{working_dir, false},
410         &shell_command.m_opaque_ptr->m_status,
411         &shell_command.m_opaque_ptr->m_signo,
412         &shell_command.m_opaque_ptr->m_output,
413         shell_command.m_opaque_ptr->m_timeout_sec);
414   });
415 }
416
417 SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
418   return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
419     return platform_sp->LaunchProcess(launch_info.ref());
420   });
421 }
422
423 SBError SBPlatform::Kill(const lldb::pid_t pid) {
424   return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
425     return platform_sp->KillProcess(pid);
426   });
427 }
428
429 SBError SBPlatform::ExecuteConnected(
430     const std::function<Status(const lldb::PlatformSP &)> &func) {
431   SBError sb_error;
432   const auto platform_sp(GetSP());
433   if (platform_sp) {
434     if (platform_sp->IsConnected())
435       sb_error.ref() = func(platform_sp);
436     else
437       sb_error.SetErrorString("not connected");
438   } else
439     sb_error.SetErrorString("invalid platform");
440
441   return sb_error;
442 }
443
444 SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {
445   SBError sb_error;
446   PlatformSP platform_sp(GetSP());
447   if (platform_sp) {
448     sb_error.ref() =
449         platform_sp->MakeDirectory(FileSpec{path, false}, file_permissions);
450   } else {
451     sb_error.SetErrorString("invalid platform");
452   }
453   return sb_error;
454 }
455
456 uint32_t SBPlatform::GetFilePermissions(const char *path) {
457   PlatformSP platform_sp(GetSP());
458   if (platform_sp) {
459     uint32_t file_permissions = 0;
460     platform_sp->GetFilePermissions(FileSpec{path, false}, file_permissions);
461     return file_permissions;
462   }
463   return 0;
464 }
465
466 SBError SBPlatform::SetFilePermissions(const char *path,
467                                        uint32_t file_permissions) {
468   SBError sb_error;
469   PlatformSP platform_sp(GetSP());
470   if (platform_sp) {
471     sb_error.ref() = platform_sp->SetFilePermissions(FileSpec{path, false},
472                                                      file_permissions);
473   } else {
474     sb_error.SetErrorString("invalid platform");
475   }
476   return sb_error;
477 }
478
479 SBUnixSignals SBPlatform::GetUnixSignals() const {
480   if (auto platform_sp = GetSP())
481     return SBUnixSignals{platform_sp};
482
483   return {};
484 }