]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/API/SBPlatform.cpp
Update LLDB snapshot to upstream r241361
[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/Core/ArchSpec.h"
15 #include "lldb/Core/Error.h"
16 #include "lldb/Host/File.h"
17 #include "lldb/Interpreter/Args.h"
18 #include "lldb/Target/Target.h"
19 #include "lldb/Target/Platform.h"
20
21 #include <functional>
22
23 using namespace lldb;
24 using namespace lldb_private;
25
26 //----------------------------------------------------------------------
27 // PlatformConnectOptions
28 //----------------------------------------------------------------------
29 struct PlatformConnectOptions {
30     PlatformConnectOptions(const char *url = NULL) :
31         m_url(),
32         m_rsync_options(),
33         m_rsync_remote_path_prefix(),
34         m_rsync_enabled(false),
35         m_rsync_omit_hostname_from_remote_path(false),
36         m_local_cache_directory ()
37     {
38         if (url && url[0])
39             m_url = url;
40     }
41     
42     ~PlatformConnectOptions()
43     {
44     }
45
46     std::string m_url;
47     std::string m_rsync_options;
48     std::string m_rsync_remote_path_prefix;
49     bool m_rsync_enabled;
50     bool m_rsync_omit_hostname_from_remote_path;
51     ConstString m_local_cache_directory;
52 };
53
54 //----------------------------------------------------------------------
55 // PlatformShellCommand
56 //----------------------------------------------------------------------
57 struct PlatformShellCommand {
58     PlatformShellCommand(const char *shell_command = NULL) :
59         m_command(),
60         m_working_dir(),
61         m_status(0),
62         m_signo(0),
63         m_timeout_sec(UINT32_MAX)
64     {
65         if (shell_command && shell_command[0])
66             m_command = shell_command;
67     }
68     
69     ~PlatformShellCommand()
70     {
71     }
72     
73     std::string m_command;
74     std::string m_working_dir;
75     std::string m_output;
76     int m_status;
77     int m_signo;
78     uint32_t m_timeout_sec;
79 };
80 //----------------------------------------------------------------------
81 // SBPlatformConnectOptions
82 //----------------------------------------------------------------------
83 SBPlatformConnectOptions::SBPlatformConnectOptions (const char *url) :
84     m_opaque_ptr(new PlatformConnectOptions(url))
85 {
86     
87 }
88
89 SBPlatformConnectOptions::SBPlatformConnectOptions(const SBPlatformConnectOptions &rhs) :
90     m_opaque_ptr(new PlatformConnectOptions())
91 {
92     *m_opaque_ptr = *rhs.m_opaque_ptr;
93 }
94     
95 SBPlatformConnectOptions::~SBPlatformConnectOptions ()
96 {
97     delete m_opaque_ptr;
98 }
99
100 void
101 SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs)
102 {
103     *m_opaque_ptr = *rhs.m_opaque_ptr;
104 }
105
106 const char *
107 SBPlatformConnectOptions::GetURL()
108 {
109     if (m_opaque_ptr->m_url.empty())
110         return NULL;
111     return m_opaque_ptr->m_url.c_str();
112 }
113     
114 void
115 SBPlatformConnectOptions::SetURL(const char *url)
116 {
117     if (url && url[0])
118         m_opaque_ptr->m_url = url;
119     else
120         m_opaque_ptr->m_url.clear();
121 }
122
123 bool
124 SBPlatformConnectOptions::GetRsyncEnabled()
125 {
126     return m_opaque_ptr->m_rsync_enabled;
127 }
128     
129 void
130 SBPlatformConnectOptions::EnableRsync (const char *options,
131                                        const char *remote_path_prefix,
132                                        bool omit_hostname_from_remote_path)
133 {
134     m_opaque_ptr->m_rsync_enabled = true;
135     m_opaque_ptr->m_rsync_omit_hostname_from_remote_path = omit_hostname_from_remote_path;
136     if (remote_path_prefix && remote_path_prefix[0])
137         m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;
138     else
139         m_opaque_ptr->m_rsync_remote_path_prefix.clear();
140
141     if (options && options[0])
142         m_opaque_ptr->m_rsync_options = options;
143     else
144         m_opaque_ptr->m_rsync_options.clear();
145
146 }
147
148 void
149 SBPlatformConnectOptions::DisableRsync ()
150 {
151     m_opaque_ptr->m_rsync_enabled = false;
152 }
153     
154 const char *
155 SBPlatformConnectOptions::GetLocalCacheDirectory()
156 {
157     return m_opaque_ptr->m_local_cache_directory.GetCString();
158 }
159     
160 void
161 SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path)
162 {
163     if (path && path[0])
164         m_opaque_ptr->m_local_cache_directory.SetCString(path);
165     else
166         m_opaque_ptr->m_local_cache_directory = ConstString();
167 }
168
169 //----------------------------------------------------------------------
170 // SBPlatformShellCommand
171 //----------------------------------------------------------------------
172 SBPlatformShellCommand::SBPlatformShellCommand (const char *shell_command) :
173     m_opaque_ptr(new PlatformShellCommand(shell_command))
174 {
175 }
176
177 SBPlatformShellCommand::SBPlatformShellCommand (const SBPlatformShellCommand &rhs) :
178     m_opaque_ptr(new PlatformShellCommand())
179 {
180     *m_opaque_ptr = *rhs.m_opaque_ptr;
181 }
182
183 SBPlatformShellCommand::~SBPlatformShellCommand()
184 {
185     delete m_opaque_ptr;
186 }
187
188 void
189 SBPlatformShellCommand::Clear()
190 {
191     m_opaque_ptr->m_output = std::move(std::string());
192     m_opaque_ptr->m_status = 0;
193     m_opaque_ptr->m_signo = 0;
194 }
195
196 const char *
197 SBPlatformShellCommand::GetCommand()
198 {
199     if (m_opaque_ptr->m_command.empty())
200         return NULL;
201     return m_opaque_ptr->m_command.c_str();
202 }
203
204 void
205 SBPlatformShellCommand::SetCommand(const char *shell_command)
206 {
207     if (shell_command && shell_command[0])
208         m_opaque_ptr->m_command = shell_command;
209     else
210         m_opaque_ptr->m_command.clear();
211 }
212
213 const char *
214 SBPlatformShellCommand::GetWorkingDirectory ()
215 {
216     if (m_opaque_ptr->m_working_dir.empty())
217         return NULL;
218     return m_opaque_ptr->m_working_dir.c_str();
219 }
220
221 void
222 SBPlatformShellCommand::SetWorkingDirectory (const char *path)
223 {
224     if (path && path[0])
225         m_opaque_ptr->m_working_dir = path;
226     else
227         m_opaque_ptr->m_working_dir.clear();
228 }
229
230 uint32_t
231 SBPlatformShellCommand::GetTimeoutSeconds ()
232 {
233     return m_opaque_ptr->m_timeout_sec;
234 }
235
236 void
237 SBPlatformShellCommand::SetTimeoutSeconds (uint32_t sec)
238 {
239     m_opaque_ptr->m_timeout_sec = sec;
240 }
241
242 int
243 SBPlatformShellCommand::GetSignal ()
244 {
245     return m_opaque_ptr->m_signo;
246 }
247
248 int
249 SBPlatformShellCommand::GetStatus ()
250 {
251     return m_opaque_ptr->m_status;
252 }
253
254 const char *
255 SBPlatformShellCommand::GetOutput ()
256 {
257     if (m_opaque_ptr->m_output.empty())
258         return NULL;
259     return m_opaque_ptr->m_output.c_str();
260 }
261
262 //----------------------------------------------------------------------
263 // SBPlatform
264 //----------------------------------------------------------------------
265 SBPlatform::SBPlatform () :
266     m_opaque_sp ()
267 {
268     
269 }
270
271 SBPlatform::SBPlatform (const char *platform_name) :
272     m_opaque_sp ()
273 {
274     Error error;
275     if (platform_name && platform_name[0])
276         m_opaque_sp = Platform::Create (ConstString(platform_name), error);
277 }
278
279 SBPlatform::~SBPlatform()
280 {
281 }
282
283 bool
284 SBPlatform::IsValid () const
285 {
286     return m_opaque_sp.get() != NULL;
287 }
288
289 void
290 SBPlatform::Clear ()
291 {
292     m_opaque_sp.reset();
293 }
294
295 const char *
296 SBPlatform::GetName ()
297 {
298     PlatformSP platform_sp(GetSP());
299     if (platform_sp)
300         return platform_sp->GetName().GetCString();
301     return NULL;
302 }
303
304 lldb::PlatformSP
305 SBPlatform::GetSP () const
306 {
307     return m_opaque_sp;
308 }
309
310 void
311 SBPlatform::SetSP (const lldb::PlatformSP& platform_sp)
312 {
313     m_opaque_sp = platform_sp;
314 }
315
316 const char *
317 SBPlatform::GetWorkingDirectory()
318 {
319     PlatformSP platform_sp(GetSP());
320     if (platform_sp)
321         return platform_sp->GetWorkingDirectory().GetCString();
322     return NULL;
323 }
324
325 bool
326 SBPlatform::SetWorkingDirectory(const char *path)
327 {
328     PlatformSP platform_sp(GetSP());
329     if (platform_sp)
330     {
331         if (path)
332             platform_sp->SetWorkingDirectory(FileSpec{path, false});
333         else
334             platform_sp->SetWorkingDirectory(FileSpec{});
335         return true;
336     }
337     return false;
338 }
339
340 SBError
341 SBPlatform::ConnectRemote (SBPlatformConnectOptions &connect_options)
342 {
343     SBError sb_error;
344     PlatformSP platform_sp(GetSP());
345     if (platform_sp && connect_options.GetURL())
346     {
347         Args args;
348         args.AppendArgument(connect_options.GetURL());
349         sb_error.ref() = platform_sp->ConnectRemote(args);
350     }
351     else
352     {
353         sb_error.SetErrorString("invalid platform");
354     }
355     return sb_error;
356 }
357
358 void
359 SBPlatform::DisconnectRemote ()
360 {
361     PlatformSP platform_sp(GetSP());
362     if (platform_sp)
363         platform_sp->DisconnectRemote();
364 }
365
366 bool
367 SBPlatform::IsConnected()
368 {
369     PlatformSP platform_sp(GetSP());
370     if (platform_sp)
371         platform_sp->IsConnected();
372     return false;
373 }
374
375 const char *
376 SBPlatform::GetTriple()
377 {
378     PlatformSP platform_sp(GetSP());
379     if (platform_sp)
380     {
381         ArchSpec arch(platform_sp->GetSystemArchitecture());
382         if (arch.IsValid())
383         {
384             // Const-ify the string so we don't need to worry about the lifetime of the string
385             return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
386         }
387     }
388     return NULL;
389 }
390
391 const char *
392 SBPlatform::GetOSBuild()
393 {
394     PlatformSP platform_sp(GetSP());
395     if (platform_sp)
396     {
397         std::string s;
398         if (platform_sp->GetOSBuildString(s))
399         {
400             if (!s.empty())
401             {
402                 // Const-ify the string so we don't need to worry about the lifetime of the string
403                 return ConstString(s.c_str()).GetCString();
404             }
405         }
406     }
407     return NULL;
408 }
409
410 const char *
411 SBPlatform::GetOSDescription()
412 {
413     PlatformSP platform_sp(GetSP());
414     if (platform_sp)
415     {
416         std::string s;
417         if (platform_sp->GetOSKernelDescription(s))
418         {
419             if (!s.empty())
420             {
421                 // Const-ify the string so we don't need to worry about the lifetime of the string
422                 return ConstString(s.c_str()).GetCString();
423             }
424         }
425     }
426     return NULL;
427 }
428
429 const char *
430 SBPlatform::GetHostname ()
431 {
432     PlatformSP platform_sp(GetSP());
433     if (platform_sp)
434         return platform_sp->GetHostname();
435     return NULL;
436 }
437
438 uint32_t
439 SBPlatform::GetOSMajorVersion ()
440 {
441     uint32_t major, minor, update;
442     PlatformSP platform_sp(GetSP());
443     if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
444         return major;
445     return UINT32_MAX;
446     
447 }
448
449 uint32_t
450 SBPlatform::GetOSMinorVersion ()
451 {
452     uint32_t major, minor, update;
453     PlatformSP platform_sp(GetSP());
454     if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
455         return minor;
456     return UINT32_MAX;
457 }
458
459 uint32_t
460 SBPlatform::GetOSUpdateVersion ()
461 {
462     uint32_t major, minor, update;
463     PlatformSP platform_sp(GetSP());
464     if (platform_sp && platform_sp->GetOSVersion(major, minor, update))
465         return update;
466     return UINT32_MAX;
467 }
468
469 SBError
470 SBPlatform::Get (SBFileSpec &src,
471                  SBFileSpec &dst)
472 {
473     SBError sb_error;
474     PlatformSP platform_sp(GetSP());
475     if (platform_sp)
476     {
477         sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
478     }
479     else
480     {
481         sb_error.SetErrorString("invalid platform");
482     }
483     return sb_error;
484 }
485
486 SBError
487 SBPlatform::Put (SBFileSpec &src,
488                  SBFileSpec &dst)
489 {
490   return ExecuteConnected(
491       [&](const lldb::PlatformSP& platform_sp)
492       {
493           if (src.Exists())
494           {
495               uint32_t permissions = src.ref().GetPermissions();
496               if (permissions == 0)
497               {
498                   if (src.ref().GetFileType() == FileSpec::eFileTypeDirectory)
499                       permissions = eFilePermissionsDirectoryDefault;
500                   else
501                       permissions = eFilePermissionsFileDefault;
502               }
503
504               return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
505           }
506
507           Error error;
508           error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
509           return error;
510       });
511 }
512
513 SBError
514 SBPlatform::Install (SBFileSpec &src,
515                      SBFileSpec &dst)
516 {
517   return ExecuteConnected(
518       [&](const lldb::PlatformSP& platform_sp)
519       {
520           if (src.Exists())
521               return platform_sp->Install(src.ref(), dst.ref());
522
523           Error error;
524           error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str());
525           return error;
526       });
527 }
528
529
530 SBError
531 SBPlatform::Run (SBPlatformShellCommand &shell_command)
532 {
533     return ExecuteConnected(
534         [&](const lldb::PlatformSP& platform_sp)
535         {
536             const char *command = shell_command.GetCommand();
537             if (!command)
538                 return Error("invalid shell command (empty)");
539
540             const char *working_dir = shell_command.GetWorkingDirectory();
541             if (working_dir == NULL)
542             {
543                 working_dir = platform_sp->GetWorkingDirectory().GetCString();
544                 if (working_dir)
545                     shell_command.SetWorkingDirectory(working_dir);
546             }
547             return platform_sp->RunShellCommand(command,
548                                                 FileSpec{working_dir, false},
549                                                 &shell_command.m_opaque_ptr->m_status,
550                                                 &shell_command.m_opaque_ptr->m_signo,
551                                                 &shell_command.m_opaque_ptr->m_output,
552                                                 shell_command.m_opaque_ptr->m_timeout_sec);
553         });
554 }
555
556 SBError
557 SBPlatform::Launch (SBLaunchInfo &launch_info)
558 {
559     return ExecuteConnected(
560         [&](const lldb::PlatformSP& platform_sp)
561         {
562             return platform_sp->LaunchProcess(launch_info.ref());
563         });
564 }
565
566 SBError
567 SBPlatform::Kill (const lldb::pid_t pid)
568 {
569     return ExecuteConnected(
570         [&](const lldb::PlatformSP& platform_sp)
571         {
572             return platform_sp->KillProcess(pid);
573         });
574 }
575
576 SBError
577 SBPlatform::ExecuteConnected (const std::function<Error(const lldb::PlatformSP&)>& func)
578 {
579     SBError sb_error;
580     const auto platform_sp(GetSP());
581     if (platform_sp)
582     {
583         if (platform_sp->IsConnected())
584             sb_error.ref() = func(platform_sp);
585         else
586             sb_error.SetErrorString("not connected");
587     }
588     else
589         sb_error.SetErrorString("invalid platform");
590
591   return sb_error;
592 }
593
594 SBError
595 SBPlatform::MakeDirectory (const char *path, uint32_t file_permissions)
596 {
597     SBError sb_error;
598     PlatformSP platform_sp(GetSP());
599     if (platform_sp)
600     {
601         sb_error.ref() = platform_sp->MakeDirectory(FileSpec{path, false}, file_permissions);
602     }
603     else
604     {
605         sb_error.SetErrorString("invalid platform");
606     }
607     return sb_error;
608 }
609
610 uint32_t
611 SBPlatform::GetFilePermissions (const char *path)
612 {
613     PlatformSP platform_sp(GetSP());
614     if (platform_sp)
615     {
616         uint32_t file_permissions = 0;
617         platform_sp->GetFilePermissions(FileSpec{path, false}, file_permissions);
618         return file_permissions;
619     }
620     return 0;
621     
622 }
623
624 SBError
625 SBPlatform::SetFilePermissions (const char *path, uint32_t file_permissions)
626 {
627     SBError sb_error;
628     PlatformSP platform_sp(GetSP());
629     if (platform_sp)
630     {
631         sb_error.ref() = platform_sp->SetFilePermissions(FileSpec{path, false}, file_permissions);
632     }
633     else
634     {
635         sb_error.SetErrorString("invalid platform");
636     }
637     return sb_error;
638     
639 }
640