Mercurial > minori
diff dep/animia/src/util/osx.cc @ 202:71832ffe425a
animia: re-add kvm fd source
this is all being merged from my wildly out-of-date laptop. SORRY!
in other news, I edited the CI file to install the wayland client
as well, so the linux CI build might finally get wayland stuff.
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Tue, 02 Jan 2024 06:05:06 -0500 |
parents | 8548dc425697 |
children | a7d0d543b334 |
line wrap: on
line diff
--- a/dep/animia/src/util/osx.cc Sun Nov 19 19:13:28 2023 -0500 +++ b/dep/animia/src/util/osx.cc Tue Jan 02 06:05:06 2024 -0500 @@ -3,23 +3,12 @@ #include <string> #include <memory> -#ifdef HAVE_COREFOUNDATION -#include <CoreFoundation/CoreFoundation.h> -#endif +#include <sys/sysctl.h> +#include <libproc.h> namespace animia::internal::osx::util { #ifdef HAVE_COREFOUNDATION -/* I don't want to have to call CFRelease */ -template<typename T> -struct CFDeleter { - using pointer = T; - void operator()(pointer p) { CFRelease(p); } -} - -template<typename T> -typedef CFReference = std::unique_ptr<T, CFDeleter>; - /* all of these LaunchServices things use *internal functions* that are subject * to change. Granted, it's not very likely that these will change very much * because I'm fairly sure Apple uses them lots in their own internal code. @@ -68,25 +57,49 @@ if (!GetLaunchServicesPrivateSymbols()) return false; - CFReference<CFTypeRef> asn = LSASNCreateWithPid(kCFAllocatorDefault, pid); + CFTypeRef asn = LSASNCreateWithPid(kCFAllocatorDefault, pid); + if (!asn) + return false; - CFReference<CFArrayRef> request_array = CFArrayCreate(NULL, (const void **)kLSDisplayNameKey, 1, NULL); + CFArrayRef request_array = CFArrayCreate(NULL, (const void **)kLSDisplayNameKey, 1, NULL); + if (!request_array) { + CFRelease(asn); + return false; + } - CFReference<CFDictionaryRef> dictionary = LSCopyApplicationInformation(kLaunchServicesMagicConstant, asn, request_array.get()); - if (!dictionary.get()) + CFDictionaryRef dictionary = LSCopyApplicationInformation(kLSDefaultSessionID, asn, request_array); + + CFRelease(request_array); + CFRelease(asn); + + if (!dictionary) return false; - CFReference<CFStringRef> str; { CFStringRef rstr; + if (!CFDictionaryGetValueIfPresent(dictionary, kLSDisplayNameKey, (CFTypeRef*)&rstr) || !rstr) return false; - str.reset(rstr); + + if (!StringFromCFString(rstr, result)) { + CFRelease(rstr); + return false; + } + + CFRelease(rstr); } - result.reserve(CFStringGetMaximumSizeForEncoding(CFStringGetLength(str.get()), kCFStringEncodingUTF8) + 1); + result.resize(result.find('\0')); + + return true; +} - if (!CFStringGetCString(str.get(), &result.front(), result.length(), result.length())) +bool StringFromCFString(CFStringRef string, std::string& result) { + if (!string) + return false; + + result.resize(CFStringGetMaximumSizeForEncoding(CFStringGetLength(string), kCFStringEncodingUTF8) + 1); + if (!CFStringGetCString(string, &result.front(), result.length(), kCFStringEncodingUTF8)) return false; return true; @@ -98,7 +111,11 @@ const int mib[3] = {CTL_KERN, KERN_PROCARGS2, static_cast<int>(pid)}; const size_t mib_size = sizeof(mib)/sizeof(*mib); - /* Get the initial size of the array */ + /* Get the initial size of the array + * + * NOTE: it IS possible for this value to change inbetween calls to sysctl(). + * Unfortunately, I couldn't care less about handling this. :) + */ size_t size; { int ret = sysctl((int*)mib, mib_size, nullptr, &size, nullptr, 0); @@ -121,6 +138,7 @@ return false; args.resize(size); + return true; } static bool GetProcessNameFromArgs(pid_t pid, std::string& result) { @@ -129,24 +147,24 @@ /* Get argc using memcpy */ int argc; - memcpy(&argc, &args.front(), sizeof(argc)); + memcpy(&result, &result.front(), sizeof(argc)); /* Do we even have argv[0]? */ if (argc < 1) return false; /* Find the first null character */ - size_t null_pos = args.find('\0', sizeof(argc)); + size_t null_pos = result.find('\0', sizeof(argc)); if (null_pos == std::string::npos) return false; /* Find the last slash */ - size_t last_slash = args.rfind('/', null_pos); + size_t last_slash = result.rfind('/', null_pos); if (last_slash == std::string::npos) return false; /* Return our result */ - result = args.substr(last_slash + 1, null_pos - last_slash - 1); + result = result.substr(last_slash + 1, null_pos - last_slash - 1); return true; } @@ -161,7 +179,7 @@ return true; } -static bool GetProcessName(pid_t pid, std::string& result) { +bool GetProcessName(pid_t pid, std::string& result) { #ifdef HAVE_COREFOUNDATION if (LaunchServicesGetProcessName(pid, result)) return true;