14#include <CoreFoundation/CoreFoundation.h>
15#include <Foundation/Foundation.h>
20#include "llvm/ADT/StringRef.h"
28+ (
id)sharedServiceContextForDeveloperDir:(NSString *)dir
29 error:(NSError **)error;
36@protocol LLDBCoreSimulatorSupport <NSObject>
37- (
id)defaultDeviceSetWithError:(NSError **)error;
41- (NSString *)identifier;
42- (NSString *)modelIdentifier;
43- (NSString *)productFamily;
44- (int32_t)productFamilyID;
47- (NSString *)versionString;
48- (NSString *)buildVersionString;
49- (BOOL)bootWithOptions:(NSDictionary *)options error:(NSError **)error;
51- (BOOL)shutdownWithError:(NSError **)error;
53- (BOOL)spawnWithPath:(NSString *)path
54 options:(nullable NSDictionary<NSString *,
id> *)options
55 terminationQueue:(nullable dispatch_queue_t)terminationQueue
56 terminationHandler:(nullable
void (^)(
int status))terminationHandler
57 pid:(pid_t *_Nullable)pid
58 error:(NSError *__autoreleasing _Nullable *_Nullable)error;
67 : m_pid(p), m_error(
error) {}
72 : m_dev(d), m_model_identifier() {}
74CoreSimulatorSupport::DeviceType::operator bool() {
return m_dev != nil; }
77 return ConstString([[m_dev identifier] UTF8String]);
81 return ConstString([[m_dev productFamily] UTF8String]);
92 : m_dev(d), m_os_version() {}
94CoreSimulatorSupport::DeviceRuntime::operator bool() {
return m_dev != nil; }
97 return [
m_dev available];
103 : m_dev(d), m_dev_type(), m_dev_runtime() {}
105CoreSimulatorSupport::Device::operator bool() {
return m_dev != nil; }
112 : m_family(), m_versions() {
113 bool first_digit =
false;
114 unsigned int val = 0;
120 val = 10 * val + (c -
'0');
121 }
else if (c ==
',') {
146 const std::string &build)
147 : m_versions(), m_build(build) {
149 unsigned int val = 0;
154 }
else if (::isdigit(c)) {
155 val = 10 * val + (c -
'0');
170 if (!m_model_identifier.has_value()) {
171 auto utf8_model_id = [[
m_dev modelIdentifier] UTF8String];
172 if (utf8_model_id && *utf8_model_id)
176 if (m_model_identifier.has_value())
177 return m_model_identifier.value();
184 if (!m_os_version.has_value()) {
185 auto utf8_ver_string = [[
m_dev versionString] UTF8String];
186 auto utf8_build_ver = [[
m_dev buildVersionString] UTF8String];
187 if (utf8_ver_string && *utf8_ver_string && utf8_build_ver &&
189 m_os_version =
OSVersion(utf8_ver_string, utf8_build_ver);
193 if (m_os_version.has_value())
194 return m_os_version.value();
199 auto utf8_name = [[
m_dev name] UTF8String];
201 return std::string(utf8_name);
206 auto utf8_name = [[
m_dev name] UTF8String];
208 return std::string(utf8_name);
213 auto utf8_udid = [[[
m_dev UDID] UUIDString] UTF8String];
215 return std::string(utf8_udid);
217 return std::string();
221 if (!m_dev_type.has_value())
224 return m_dev_type.value();
229 if (!m_dev_runtime.has_value())
232 return m_dev_runtime.value();
348#define kSimDeviceBootPersist \
352 NSDictionary *options = @{
356#undef kSimDeviceBootPersist
359 if ([m_dev bootWithOptions:options
error:&nserror]) {
370 if ([m_dev shutdownWithError:&nserror]) {
380 NSMutableDictionary *options, NSString *key,
390 error.SetErrorStringWithFormat(
"close file action for %i not supported",
395 error.SetErrorStringWithFormat(
396 "duplication file action for %i not supported", fd);
406 if (file_spec == secondary_spec) {
411 return Status(std::move(Err));
415 [options setValue:[NSNumber numberWithInteger:secondary_fd]
424 if (created_fd >= 0) {
428 else if (oflag & O_WRONLY)
430 else if (oflag & O_RDONLY)
432 file = std::make_shared<NativeFile>(created_fd, file_options,
true);
433 [options setValue:[NSNumber numberWithInteger:created_fd] forKey:key];
437 error.SetErrorStringWithFormat(
"unable to open file '%s': %s",
450#define kSimDeviceSpawnEnvironment \
453#define kSimDeviceSpawnStdin @"stdin"
454#define kSimDeviceSpawnStdout @"stdout"
456#define kSimDeviceSpawnStderr @"stderr"
458#define kSimDeviceSpawnArguments \
461#define kSimDeviceSpawnWaitForDebugger \
463#define kSimDeviceSpawnStandalone @"standalone"
465 NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
467 options[kSimDeviceSpawnStandalone] = @(YES);
469 if (launch_info.
GetFlags().
Test(lldb::eLaunchFlagDebug))
474 NSMutableArray *args_array = [[NSMutableArray alloc] init];
480 [options setObject:args_array forKey:kSimDeviceSpawnArguments];
483 NSMutableDictionary *env_dict = [[NSMutableDictionary alloc] init];
486 NSString *key_ns = [NSString stringWithUTF8String:KV.first().str().c_str()];
487 NSString *value_ns = [NSString stringWithUTF8String:KV.second.c_str()];
489 [env_dict setValue:value_ns forKey:key_ns];
492 [options setObject:env_dict forKey:kSimDeviceSpawnEnvironment];
499 STDIN_FILENO, stdin_file);
505 STDOUT_FILENO, stdout_file);
511 STDERR_FILENO, stderr_file);
516#undef kSimDeviceSpawnEnvironment
517#undef kSimDeviceSpawnStdin
518#undef kSimDeviceSpawnStdout
519#undef kSimDeviceSpawnStderr
520#undef kSimDeviceSpawnWaitForDebugger
521#undef kSimDeviceSpawnArguments
526 BOOL success = [
m_dev
527 spawnWithPath:[NSString stringWithUTF8String:launch_info
533 terminationHandler:nil
538 const char *nserror_string = [[nserror description] UTF8String];
539 error.SetErrorString(nserror_string ? nserror_string :
"unable to launch");
547 if (!developer_dir || !developer_dir[0])
550 Class SimServiceContextClass = NSClassFromString(
@"SimServiceContext");
551 NSString *dev_dir = @(developer_dir);
552 NSError *
error = nil;
555 [SimServiceContextClass sharedServiceContextForDeveloperDir:dev_dir
560 return DeviceSet([[serviceContext defaultDeviceSetWithError:&
error] devices]);
565 const char *developer_dir) {
573 return [
m_dev count];
578 if (idx < GetNumDevices())
579 return Device([m_dev objectAtIndex:idx]);
585 NSMutableArray *array = [[NSMutableArray alloc] init];
586 for (NSUInteger i = 0; i < GetNumDevices(); i++) {
587 Device d(GetDeviceAtIndex(i));
589 [array addObject:(id)d.m_dev];
596 std::function<
bool(
const Device &)> f) {
597 const size_t n = GetNumDevices();
598 for (NSUInteger i = 0; i < n; ++i) {
599 if (!f(GetDeviceAtIndex(i)))
606 NSMutableArray *array = [[NSMutableArray alloc] init];
607 const size_t n = GetNumDevices();
608 for (NSUInteger i = 0; i < n; ++i) {
609 Device d(GetDeviceAtIndex(i));
610 if (d && d.GetDeviceType() &&
611 d.GetDeviceType().GetProductFamilyID() == dev_id)
612 [array addObject:(id)d.m_dev];
615 return DeviceSet(array);
622 for (NSUInteger i = 0; i < GetNumDevices(); i++) {
623 Device d(GetDeviceAtIndex(i));
630 dev.GetDeviceType().GetModelIdentifier()) ||
632 dev.GetDeviceRuntime().GetVersion())
static llvm::raw_ostream & error(Stream &strm)
static DeviceSet GetAvailableDevices(const char *developer_dir)
Device GetFanciest(DeviceType::ProductFamilyID dev_id)
void ForEach(std::function< bool(const Device &)> f)
DeviceSet GetDevices(DeviceType::ProductFamilyID dev_id)
static DeviceSet GetAllDevices(const char *developer_dir)
DeviceSet GetDevicesIf(std::function< bool(Device)> f)
Device GetDeviceAtIndex(size_t idx)
ProductFamilyID GetProductFamilyID()
ModelIdentifier GetModelIdentifier()
lldb_private::ConstString GetIdentifier()
lldb_private::ConstString GetProductFamily()
Process Spawn(lldb_private::ProcessLaunchInfo &launch_info)
std::string GetUDID() const
std::string GetName() const
DeviceRuntime GetDeviceRuntime()
bool Boot(lldb_private::Status &err)
DeviceType GetDeviceType()
unsigned int GetVersionAtIndex(size_t idx) const
std::vector< unsigned int > m_versions
std::string GetFamily() const
size_t GetNumVersions() const
std::vector< unsigned int > m_versions
unsigned int GetVersionAtIndex(size_t idx) const
size_t GetNumVersions() const
A command line argument class.
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
A uniqued constant string class.
int GetActionArgument() const
const FileSpec & GetFileSpec() const
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
bool Test(ValueType bit) const
Test a single flag bit.
Environment & GetEnvironment()
PseudoTerminal & GetPTY()
const FileAction * GetFileActionForFD(int fd) const
llvm::Error OpenSecondary(int oflag)
Open the secondary for the current primary pseudo terminal.
int GetPrimaryFileDescriptor() const
The primary file descriptor accessor.
std::string GetSecondaryName() const
Get the name of the secondary pseudo terminal.
int GetSecondaryFileDescriptor() const
The secondary file descriptor accessor.
@ invalid_fd
Invalid file descriptor value.
void Clear()
Clear the object state.
void SetErrorToErrno()
Set the current error to errno.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
#define LLDB_INVALID_PROCESS_ID
bool operator>(const OSVersion &lhs, const OSVersion &rhs)
bool operator!=(const OSVersion &lhs, const OSVersion &rhs)
bool operator==(const OSVersion &lhs, const OSVersion &rhs)
bool operator<(const OSVersion &lhs, const OSVersion &rhs)
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::File > FileSP