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;