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