comparison dep/animia/src/util/osx.cc @ 169:e44b7c428d7c

dep/animia: add libkvm method (UNTESTED)
author Paper <mrpapersonic@gmail.com>
date Sun, 19 Nov 2023 17:30:38 -0500
parents 8937fb7f2d66
children c413e475f496
comparison
equal deleted inserted replaced
168:79a2a24453fa 169:e44b7c428d7c
1 #include "animia/util/osx.h" 1 #include "animia/util/osx.h"
2
3 #include <string>
4 #include <memory>
2 5
3 #ifdef HAVE_COREFOUNDATION 6 #ifdef HAVE_COREFOUNDATION
4 #include <CoreFoundation/CoreFoundation.h> 7 #include <CoreFoundation/CoreFoundation.h>
5 #endif 8 #endif
6 9
7 namespace animia::internal::osx::util { 10 namespace animia::internal::osx::util {
8 11
9 #ifdef HAVE_COREFOUNDATION 12 #ifdef HAVE_COREFOUNDATION
10 /* All of these LaunchServices things use *internal functions* that are subject 13 /* I don't want to have to call CFRelease */
11 ** to change. Granted, it's not very likely that these will change very much 14 template<typename T>
12 ** because I'm fairly sure Apple uses them lots in their own internal code. 15 struct CFDeleter {
16 using pointer = T;
17 void operator()(pointer p) { CFRelease(p); }
18 }
19
20 template<typename T>
21 typedef CFReference = std::unique_ptr<T, CFDeleter>;
22
23 /* all of these LaunchServices things use *internal functions* that are subject
24 * to change. Granted, it's not very likely that these will change very much
25 * because I'm fairly sure Apple uses them lots in their own internal code.
13 */ 26 */
14
15 /* from RDProcess */
16 typedef CFTypeRef (*LSASNCreateWithPidSpec)(CFAllocatorRef, pid_t); 27 typedef CFTypeRef (*LSASNCreateWithPidSpec)(CFAllocatorRef, pid_t);
17 typedef CFDictionaryRef (*LSCopyApplicationInformationSpec)(int, CFTypeRef, CFArrayRef); 28 typedef CFDictionaryRef (*LSCopyApplicationInformationSpec)(int, CFTypeRef, CFArrayRef);
18 29
19 static LSCopyApplicationInformationSpec LSCopyApplicationInformation = nullptr; 30 static LSCopyApplicationInformationSpec LSCopyApplicationInformation = nullptr;
20 static LSASNCreateWithPidSpec LSASNCreateWithPid = nullptr; 31 static LSASNCreateWithPidSpec LSASNCreateWithPid = nullptr;
21 32
22 /* retrieved from LaunchServicesSPI.h in WebKit */ 33 /* retrieved from LaunchServicesSPI.h in WebKit */
23 static constexpr int kLSDefaultSessionID = -2; 34 static constexpr int kLSDefaultSessionID = -2;
35
24 static const CFStringRef kLaunchServicesBundleID = CFSTR("com.apple.LaunchServices"); 36 static const CFStringRef kLaunchServicesBundleID = CFSTR("com.apple.LaunchServices");
25 37
26 /* retrieved dynamically */ 38 /* retrieved dynamically */
27 static CFStringRef kLSDisplayNameKey = nullptr; 39 static CFStringRef kLSDisplayNameKey = nullptr;
28 static CFStringRef kLSPIDKey = nullptr; 40 static CFStringRef kLSPIDKey = nullptr;
54 static bool LaunchServicesGetProcessName(pid_t pid, std::string& result) { 66 static bool LaunchServicesGetProcessName(pid_t pid, std::string& result) {
55 if (!LSCopyApplicationInformation || !LSASNCreateWithPid) 67 if (!LSCopyApplicationInformation || !LSASNCreateWithPid)
56 if (!GetLaunchServicesPrivateSymbols()) 68 if (!GetLaunchServicesPrivateSymbols())
57 return false; 69 return false;
58 70
59 CFTypeRef asn = LSASNCreateWithPid(kCFAllocatorDefault, pid); 71 CFReference<CFTypeRef> asn = LSASNCreateWithPid(kCFAllocatorDefault, pid);
60 72
61 CFArrayRef request_array = CFArrayCreate(NULL, (const void **)kLSDisplayNameKey, 1, NULL); 73 CFReference<CFArrayRef> request_array = CFArrayCreate(NULL, (const void **)kLSDisplayNameKey, 1, NULL);
62 74
63 CFDictionaryRef dictionary = LSCopyApplicationInformation(kLaunchServicesMagicConstant, asn, request_array); 75 CFReference<CFDictionaryRef> dictionary = LSCopyApplicationInformation(kLaunchServicesMagicConstant, asn, request_array.get());
64 76 if (!dictionary.get())
65 CFRelease(request_array);
66 if (!dictionary)
67 return false; 77 return false;
68 78
69 CFStringRef str; 79 CFReference<CFStringRef> str;
70 if (!CFDictionaryGetValueIfPresent(dictionary, kLSDisplayNameKey, (CFTypeRef*)&str) || !str) { 80 {
71 CFRelease(dictionary); 81 CFStringRef rstr;
72 return false; 82 if (!CFDictionaryGetValueIfPresent(dictionary, kLSDisplayNameKey, (CFTypeRef*)&rstr) || !rstr)
73 } 83 return false;
74 CFRetain(str); 84 str.reset(rstr);
75
76 CFRelease(dictionary);
77
78 result.reserve(CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8) + 1);
79
80 if (!CFStringGetCString(str, &result.front(), result.length(), result.length())) {
81 CFRelease(str);
82 return false;
83 } 85 }
84 86
85 CFRelease(str); 87 result.reserve(CFStringGetMaximumSizeForEncoding(CFStringGetLength(str.get()), kCFStringEncodingUTF8) + 1);
88
89 if (!CFStringGetCString(str.get(), &result.front(), result.length(), result.length()))
90 return false;
86 91
87 return true; 92 return true;
88 } 93 }
89 #endif // HAVE_COREFOUNDATION 94 #endif // HAVE_COREFOUNDATION
90 95