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