changeset 269:3efac0541151

chore: merge
author Paper <paper@paper.us.eu.org>
date Fri, 12 Apr 2024 05:23:45 -0400
parents 382b50754fe4 (diff) 09c5bd74fe93 (current diff)
children 0718f538c5f9
files
diffstat 3 files changed, 77 insertions(+), 199 deletions(-) [+]
line wrap: on
line diff
--- a/dep/animone/include/animone/util/osx.h	Thu Apr 11 23:39:18 2024 -0400
+++ b/dep/animone/include/animone/util/osx.h	Fri Apr 12 05:23:45 2024 -0400
@@ -4,35 +4,12 @@
 #include "animone/types.h"
 #include <cstdint>
 #include <string>
+#include <memory>
 
 #include <CoreFoundation/CoreFoundation.h>
 
 namespace animone::internal::osx::util {
 
-template<typename T>
-bool GetCFNumber(CFNumberRef num, T& result) {
-	if (!num)
-		return false;
-
-	int64_t res;
-	if (!CFNumberGetValue(num, static_cast<CFNumberType>(4), &res))
-		return false;
-
-	result = static_cast<T>(res);
-	return true;
-}
-
-template<typename T>
-struct CFDeconstructor {
-	using pointer = T;
-	void operator()(pointer t) const { ::CFRelease(t); };
-};
-
-template<typename T>
-using CFPtr = vector<T, CFDecontructor<T>>; // type-id is vector<T, Alloc<T>>
-
-bool StringFromCFString(CFStringRef string, std::string& result);
-
 bool GetProcessName(pid_t pid, std::string& result);
 
 } // namespace animone::internal::osx::util
--- a/dep/animone/src/util/osx.cc	Thu Apr 11 23:39:18 2024 -0400
+++ b/dep/animone/src/util/osx.cc	Fri Apr 12 05:23:45 2024 -0400
@@ -8,167 +8,30 @@
 
 namespace animone::internal::osx::util {
 
-typedef CFTypeRef (*LSASNCreateWithPidSpec)(CFAllocatorRef, pid_t);
-typedef CFDictionaryRef (*LSCopyApplicationInformationSpec)(int, CFTypeRef, CFArrayRef);
-
-/* retrieved dynamically from launchservices */
-static LSCopyApplicationInformationSpec LSCopyApplicationInformation = nullptr;
-static LSASNCreateWithPidSpec LSASNCreateWithPid = nullptr;
-
-static CFStringRef kLSDisplayNameKey = nullptr;
-static CFStringRef kLSPIDKey = nullptr;
-
-/* retrieved from LaunchServicesSPI.h in WebKit */
-static constexpr int kLSDefaultSessionID = -2;
+static bool GetProcessNameFromProcPidPath(pid_t pid, std::string& result) {
+	result.assign(PROC_PIDPATHINFO_MAXSIZE, '\0');
 
-static const CFStringRef kLaunchServicesBundleID = CFSTR("com.apple.LaunchServices");
-
-static bool GetLaunchServicesPrivateSymbols() {
-	CFBundleRef launch_services_bundle = CFBundleGetBundleWithIdentifier(kLaunchServicesBundleID);
-	if (!launch_services_bundle)
-		return false;
-
-	LSCopyApplicationInformation = reinterpret_cast<LSCopyApplicationInformationSpec>(
-	    CFBundleGetFunctionPointerForName(launch_services_bundle, CFSTR("_LSCopyApplicationInformation")));
-	if (!LSCopyApplicationInformation)
-		return false;
-
-	LSASNCreateWithPid = reinterpret_cast<LSASNCreateWithPidSpec>(
-	    CFBundleGetFunctionPointerForName(launch_services_bundle, CFSTR("_LSASNCreateWithPid")));
-	if (!LSASNCreateWithPid)
+	int ret = proc_pidpath(pid, result.data(), result.size() * sizeof(char));
+	if (ret <= 0)
 		return false;
 
-	CFStringRef* ptr_kLSDisplayNameKey = reinterpret_cast<CFStringRef*>(
-	    CFBundleGetDataPointerForName(launch_services_bundle, CFSTR("_kLSDisplayNameKey")));
-	if (!ptr_kLSDisplayNameKey)
-		return false;
-	kLSDisplayNameKey = *ptr_kLSDisplayNameKey;
-
-	CFStringRef* ptr_kLSPIDKey =
-	    reinterpret_cast<CFStringRef*>(CFBundleGetDataPointerForName(launch_services_bundle, CFSTR("_kLSPIDKey")));
-	if (!ptr_kLSPIDKey)
-		return false;
-	kLSPIDKey = *ptr_kLSPIDKey;
-
-	return true;
-}
-
-static bool LaunchServicesGetProcessName(pid_t pid, std::string& result) {
-	if (!LSCopyApplicationInformation || !LSASNCreateWithPid || !kLSDisplayNameKey || !kLSPIDKey)
-		if (!GetLaunchServicesPrivateSymbols())
-			return false;
+	/* find the last slash, if there's none, we're done here */
+	size_t last_slash = result.rfind('/');
+	if (last_slash == std::string::npos)
+		return true;
 
-	/* what the hell is an `asn`? */
-	CFPtr<CFTypeRef> asn = LSASNCreateWithPid(kCFAllocatorDefault, pid);
-	if (!asn)
-		return false;
-
-	CFPtr<CFArrayRef> request_array = CFArrayCreate(NULL, (const void**)kLSDisplayNameKey, 1, NULL);
-	if (!request_array)
-		return false;
-
-	CFPtr<CFDictionaryRef> dictionary =
-	    LSCopyApplicationInformation(kLSDefaultSessionID, asn.get(), request_array.get());
-	if (!dictionary)
-		return false;
-
-	{
-		/* this doesn't need to be free'd */
-		CFStringRef rstr;
-
-		if (!CFDictionaryGetValueIfPresent(dictionary, kLSDisplayNameKey, (CFTypeRef*)&rstr) || !rstr)
-			return false;
-
-		if (!StringFromCFString(rstr, result))
-			return false;
-	}
-
-	result.resize(result.find('\0'));
-
+	result.erase(0, last_slash + 1);
 	return true;
 }
 
-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;
-}
-
-static bool GetProcessArgs(pid_t pid, std::string& args) {
-	/* sysctl shouldn't touch these, so we define them as 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
-	 *
-	 * NOTE: it IS possible for this value to change inbetween calls to sysctl().
-	 * Unfortunately, I couldn't care less about handling this. :)
-	 *
-	 * is that really true, though? these should be constant values. but are
-	 * argc and argv *really* constant?
-	 */
-	size_t size;
-	{
-		int ret = sysctl((int*)mib, mib_size, nullptr, &size, nullptr, 0);
-		if (ret)
-			return false;
-	}
-
-	/* Reserve the space for it in args */
-	args.resize(size);
-
-	/* Get the contents of argc and argv */
-	{
-		int ret = sysctl((int*)mib, mib_size, &args.front(), &size, NULL, 0);
-		if (ret)
-			return false;
-	}
-
-	/* Is the size big enough to hold at least argc? */
-	if (size < sizeof(int))
-		return false;
-
-	args.resize(size);
-	return true;
-}
-
-static bool GetProcessNameFromArgs(pid_t pid, std::string& result) {
-	if (!GetProcessArgs(pid, result))
-		return false;
-
-	/* Get argc using memcpy */
-	int argc = 0;
-	memcpy(&argc, &result.front(), sizeof(argc));
-
-	/* Do we even have argv[0]? */
-	if (argc < 1)
-		return false;
-
-	/* Find the first null character */
-	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 = result.rfind('/', null_pos);
-	if (last_slash == std::string::npos)
-		return false;
-
-	/* Return our result */
-	result = result.substr(last_slash + 1, null_pos - last_slash - 1);
-	return true;
-}
-
-static bool GetProcessNameFromKernel(pid_t pid, std::string& result) {
-	result.resize(2 * MAXCOMLEN);
+static bool GetProcessNameFromProcName(pid_t pid, std::string& result) {
+	result.assign(2 * MAXCOMLEN, '\0');
 
 	int size = proc_name(pid, &result.front(), result.length());
-	if (!size)
+
+	/* if size is MAXCOMLEN or 2 * MAXCOMLEN, assume
+	 * this method won't work and our result is truncated */
+	if (size <= 0 || size == MAXCOMLEN || size == 2 * MAXCOMLEN)
 		return false;
 
 	result.resize(size);
@@ -176,18 +39,10 @@
 }
 
 bool GetProcessName(pid_t pid, std::string& result) {
-	if (LaunchServicesGetProcessName(pid, result))
+	if (GetProcessNameFromProcName(pid, result))
 		return true;
 
-	/* Try parsing the arguments, this prevents the process name being
-	 * cut off to 2*MAXCOMLEN (32 chars) */
-	if (GetProcessNameFromArgs(pid, result))
-		return true;
-
-	/* Then attempt getting it from the kernel, which results in the
-	 * process name being cut to 32 chars (worse, 16 chars if p_name is
-	 * unavailable) */
-	if (GetProcessNameFromKernel(pid, result))
+	if (GetProcessNameFromProcPidPath(pid, result))
 		return true;
 
 	return false;
--- a/dep/animone/src/win/quartz.cc	Thu Apr 11 23:39:18 2024 -0400
+++ b/dep/animone/src/win/quartz.cc	Fri Apr 12 05:23:45 2024 -0400
@@ -17,6 +17,9 @@
 
 namespace animone::internal::quartz {
 
+template<typename T>
+using CFPtr = std::unique_ptr<T, CFDecontructor<T>>;
+
 #if __LP64__
 typedef long NSInteger;
 #else
@@ -58,21 +61,51 @@
 }
 
 template<typename T>
+static bool GetCFNumber(CFNumberRef num, T& result) {
+	if (!num)
+		return false;
+
+	int64_t res;
+	if (!CFNumberGetValue(num, static_cast<CFNumberType>(4), &res))
+		return false;
+
+	result = static_cast<T>(res);
+	return true;
+}
+
+static 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;
+}
+
+template<typename T>
 static bool CFDictionaryGetValue(CFDictionaryRef thedict, CFStringRef key, T& out) {
 	CFTypeRef data = nullptr;
 	if (!CFDictionaryGetValueIfPresent(thedict, key, reinterpret_cast<const void**>(&data)) || !data)
 		return false;
 
 	if constexpr (std::is_arithmetic<T>::value)
-		osx::util::GetCFNumber(reinterpret_cast<CFNumberRef>(data), out);
+		GetCFNumber(reinterpret_cast<CFNumberRef>(data), out);
 	else if constexpr (std::is_same<T, std::string>::value)
-		osx::util::StringFromCFString(reinterpret_cast<CFStringRef>(data), out);
+		StringFromCFString(reinterpret_cast<CFStringRef>(data), out);
 	else
 		return false;
 
 	return true;
 }
 
+template<typename T>
+struct CFDeconstructor {
+	using pointer = T;
+	void operator()(pointer t) const { ::CFRelease(t); };
+};
+
 static bool GetWindowTitleAccessibility(unsigned int wid, pid_t pid, std::string& result) {
 	CGRect bounds = {0};
 	{
@@ -119,24 +152,39 @@
 		    kAXErrorSuccess) {
 			CGPoint point;
 			if (!AXValueGetValue(val, kAXValueTypeCGPoint, reinterpret_cast<CFTypeRef>(&point)) ||
-			    (point.x != bounds.origin.x || point.y != bounds.origin.y))
+			    (point.x != bounds.origin.x || point.y != bounds.origin.y)) {
+				CFRelease(val);
 				continue;
-		} else
+			}
+		} else {
+			CFRelease(val);
 			continue;
+		}
+
+		CFRelease(val);
 
 		if (AXUIElementCopyAttributeValue(window, kAXSizeAttribute, reinterpret_cast<CFTypeRef*>(&val)) ==
 		    kAXErrorSuccess) {
 			CGSize size;
 			if (!AXValueGetValue(val, kAXValueTypeCGSize, reinterpret_cast<CFTypeRef>(&size)) ||
-			    (size.width != bounds.size.width || size.height != bounds.size.height))
+			    (size.width != bounds.size.width || size.height != bounds.size.height)) {
+				CFRelease(val);
 				continue;
-		} else
+			}
+		} else {
+			CFRelease(val);
 			continue;
+		}
+
+		CFRelease(val);
 
 		CFStringRef title;
 		if (AXUIElementCopyAttributeValue(window, kAXTitleAttribute, reinterpret_cast<CFTypeRef*>(&title)) ==
-		    kAXErrorSuccess)
-			return osx::util::StringFromCFString(title, result);
+		    kAXErrorSuccess) {
+			bool success = StringFromCFString(title, result);
+			CFRelease(title);
+			return success;
+		}
 	}
 
 	return false;
@@ -152,7 +200,7 @@
 			title.reset(t);
 		}
 
-		if (title && CFStringGetLength(title.get()) && osx::util::StringFromCFString(title.get(), result))
+		if (title && CFStringGetLength(title.get()) && StringFromCFString(title.get(), result))
 			return true;
 	}
 
@@ -171,8 +219,7 @@
 	if (!bundle_id)
 		return false;
 
-	result = osx::util::StringFromCFString(bundle_id, result);
-	return true;
+	return StringFromCFString(bundle_id, result);
 }
 
 static bool GetProcessBundleIdentifierOld(pid_t pid, std::string& result) {
@@ -189,8 +236,7 @@
 	if (!value)
 		return false;
 
-	result = osx::util::StringFromCFString(value, result);
-	return true;
+	return StringFromCFString(value, result);
 }
 
 static bool GetProcessBundleIdentifier(pid_t pid, std::string& result) {