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;
37 - (
id)defaultDeviceSetWithError:(NSError **)error;
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() {}
74 CoreSimulatorSupport::DeviceType::operator bool() {
return m_dev != nil; }
92 : m_dev(d), m_os_version() {}
94 CoreSimulatorSupport::DeviceRuntime::operator bool() {
return m_dev != nil; }
97 return [
m_dev available];
103 : m_dev(d), m_dev_type(), m_dev_runtime() {}
105 CoreSimulatorSupport::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 ==
',') {
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.hasValue()) {
171 auto utf8_model_id = [[
m_dev modelIdentifier] UTF8String];
172 if (utf8_model_id && *utf8_model_id)
176 if (m_model_identifier.hasValue())
177 return m_model_identifier.getValue();
184 if (!m_os_version.hasValue()) {
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.hasValue())
194 return m_os_version.getValue();
199 auto utf8_name = [[
m_dev name] UTF8String];
206 auto utf8_name = [[
m_dev name] UTF8String];
213 auto utf8_udid = [[[
m_dev UDID] UUIDString] UTF8String];
221 if (!m_dev_type.hasValue())
224 return m_dev_type.getValue();
229 if (!m_dev_runtime.hasValue())
232 return m_dev_runtime.getValue();
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,
381 const int fd, lldb::FileSP &file) {
386 case FileAction::eFileActionNone:
389 case FileAction::eFileActionClose:
390 error.SetErrorStringWithFormat(
"close file action for %i not supported",
394 case FileAction::eFileActionDuplicate:
395 error.SetErrorStringWithFormat(
396 "duplication file action for %i not supported", fd);
399 case FileAction::eFileActionOpen: {
403 if (primary_fd != PseudoTerminal::invalid_fd) {
406 if (file_spec == secondary_spec) {
409 if (secondary_fd == PseudoTerminal::invalid_fd) {
411 return Status(std::move(Err));
414 assert(secondary_fd != PseudoTerminal::invalid_fd);
415 [options setValue:[NSNumber numberWithInteger:secondary_fd]
424 if (created_fd >= 0) {
427 file_options |= File::eOpenOptionReadWrite;
428 else if (oflag & O_WRONLY)
429 file_options |= File::eOpenOptionWriteOnly;
430 else if (oflag & O_RDONLY)
431 file_options |= File::eOpenOptionReadOnly;
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];
495 lldb::FileSP stdin_file;
496 lldb::FileSP stdout_file;
497 lldb::FileSP stderr_file;
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
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];
622 for (NSUInteger i = 0; i < GetNumDevices(); i++) {
623 Device d(GetDeviceAtIndex(i));
630 dev.GetDeviceType().GetModelIdentifier()) ||
632 dev.GetDeviceRuntime().GetVersion())