changeset 163:44c5e6dd9488

dep/animia/osx: move GetProcessName to util/osx so we can use it in quartz
author Paper <mrpapersonic@gmail.com>
date Sat, 18 Nov 2023 00:47:40 -0500
parents 61b76c7b656a
children 99fdf5a90b0f
files dep/animia/CMakeLists.txt dep/animia/include/animia/util/osx.h dep/animia/src/fd/linux.cc dep/animia/src/fd/xnu.cc dep/animia/src/util/osx.cc dep/animia/src/win/quartz.mm
diffstat 6 files changed, 120 insertions(+), 107 deletions(-) [+]
line wrap: on
line diff
--- a/dep/animia/CMakeLists.txt	Fri Nov 17 16:49:57 2023 -0500
+++ b/dep/animia/CMakeLists.txt	Sat Nov 18 00:47:40 2023 -0500
@@ -21,13 +21,15 @@
 	list(APPEND SRC_FILES
 		# xnu stuff
 		src/fd/xnu.cc
+		src/util/osx.cc
 	)
 
 	include(CheckIncludeFile)
 	check_include_file("CoreFoundation/CoreFoundation.h" HAVE_COREFOUNDATION)
+	# If you're building on OS X, you most likely do have this file, but we
+	# check anyway.
 	if (HAVE_COREFOUNDATION)
 		list(APPEND DEFINES HAVE_COREFOUNDATION)
-		list(APPEND SRC_FILES src/util/osx.cc)
 	endif()
 
 	check_language(OBJCXX)
--- a/dep/animia/include/animia/util/osx.h	Fri Nov 17 16:49:57 2023 -0500
+++ b/dep/animia/include/animia/util/osx.h	Sat Nov 18 00:47:40 2023 -0500
@@ -6,7 +6,7 @@
 
 namespace animia::internal::osx::util {
 
-bool LaunchServicesGetProcessName(pid_t pid, std::string& result);
+bool GetProcessName(pid_t pid, std::string& result);
 
 }
 
--- a/dep/animia/src/fd/linux.cc	Fri Nov 17 16:49:57 2023 -0500
+++ b/dep/animia/src/fd/linux.cc	Sat Nov 18 00:47:40 2023 -0500
@@ -22,7 +22,7 @@
 
 /* this uses dirent instead of std::filesystem; it would make a bit
    more sense to use the latter, but this is platform dependent already :) */
-std::vector<std::string> GetAllFilesInDir(const std::string& _dir) {
+static std::vector<std::string> GetAllFilesInDir(const std::string& _dir) {
 	std::vector<std::string> ret;
 
 	DIR* dir = opendir(_dir.c_str());
@@ -39,7 +39,7 @@
 	return ret;
 }
 
-std::string Basename(const std::string& path) {
+static std::string Basename(const std::string& path) {
 	return path.substr(path.find_last_of("/") + 1, path.length());
 }
 
--- a/dep/animia/src/fd/xnu.cc	Fri Nov 17 16:49:57 2023 -0500
+++ b/dep/animia/src/fd/xnu.cc	Sat Nov 18 00:47:40 2023 -0500
@@ -24,88 +24,6 @@
 
 namespace animia::internal::xnu {
 
-static bool GetProcessNameFromArgs(pid_t pid, std::string& result) {
-	/* sysctl shouldn't touch these, so we define them as const */
-	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 */
-	size_t size;
-	{
-		int ret = sysctl((int*)mib, mib_size, nullptr, &size, nullptr, 0);
-		if (ret)
-			return false;
-	}
-
-	/* Reserve the space for it in a std::string */
-	std::string 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);
-
-	/* Get argc using memcpy */
-	int argc;
-	memcpy(&argc, &args.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));
-	if (null_pos == std::string::npos)
-		return false;
-
-	/* Find the last slash */
-	size_t last_slash = args.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);
-	return true;
-}
-
-static bool GetProcessNameFromKernel(pid_t pid, std::string& result) {
-	result.reserve(2*MAXCOMLEN);
-	if (!proc_name(pid, &result.front(), result.length()))
-		return false;
-
-	result.shrink_to_fit();
-	return true;
-}
-
-static bool GetProcessName(pid_t pid, std::string& result) {
-	/* Use LaunchServices */
-#ifdef HAVE_COREFOUNDATION
-	if (osx::util::LaunchServicesGetProcessName(pid, result))
-		return true;
-#endif
-
-	/* 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 (16 chars if p_name is unavailable) */
-	if (GetProcessNameFromKernel(pid, result))
-		return true;
-
-	return false;
-}
-
 bool XnuFdTools::EnumerateOpenProcesses(process_proc_t process_proc) {
 	size_t pids_size = 512;
 	std::unique_ptr<pid_t[]> pids;
@@ -120,7 +38,7 @@
 
 	for (int i = 0; i < pids_size; i++) {
 		std::string result;
-		GetProcessName(pids[i], result);
+		osx::util::GetProcessName(pids[i], result);
 		if (!process_proc({pids[i], result}))
 			return false;
 	}
--- a/dep/animia/src/util/osx.cc	Fri Nov 17 16:49:57 2023 -0500
+++ b/dep/animia/src/util/osx.cc	Sat Nov 18 00:47:40 2023 -0500
@@ -1,55 +1,59 @@
-/* A wrapper around multiple LaunchServices things */
-
 #include "animia/util/osx.h"
 
+#ifdef HAVE_COREFOUNDATION
 #include <CoreFoundation/CoreFoundation.h>
-
-#include <iostream>
+#endif
 
 namespace animia::internal::osx::util {
 
-#define RDSymbolNameStr(symbol) (CFSTR("_"#symbol))
+#ifdef HAVE_COREFOUNDATION
+/* 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.
+*/
 
-static constexpr int kLaunchServicesMagicConstant = -2; // or -1, dunno the difference
-
+/* from RDProcess */
 typedef CFTypeRef (*LSASNCreateWithPidSpec)(CFAllocatorRef, pid_t);
 typedef CFDictionaryRef (*LSCopyApplicationInformationSpec)(int, CFTypeRef, CFArrayRef);
 
 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 const CFStringRef kLaunchServicesBundleID = CFSTR("com.apple.LaunchServices");
 
-static CFStringRef (kLaunchServicesBundleID) = CFSTR("com.apple.LaunchServices");
+/* retrieved dynamically */
+static CFStringRef kLSDisplayNameKey = nullptr;
+static CFStringRef kLSPIDKey = nullptr;
 
-static bool FindLaunchServicesPrivateSymbols() {
+static bool GetLaunchServicesPrivateSymbols() {
 	CFBundleRef launch_services_bundle = CFBundleGetBundleWithIdentifier(kLaunchServicesBundleID);
 	if (!launch_services_bundle)
 		return false;
 
-	LSCopyApplicationInformation = (LSCopyApplicationInformationSpec)CFBundleGetFunctionPointerForName(launch_services_bundle, RDSymbolNameStr(LSCopyApplicationInformation));
+	LSCopyApplicationInformation = (LSCopyApplicationInformationSpec)CFBundleGetFunctionPointerForName(launch_services_bundle, CFSTR("_LSCopyApplicationInformation"));
 	if (!LSCopyApplicationInformation)
 		return false;
 
-	LSASNCreateWithPid = (LSASNCreateWithPidSpec)CFBundleGetFunctionPointerForName(launch_services_bundle, RDSymbolNameStr(LSASNCreateWithPid));
+	LSASNCreateWithPid = (LSASNCreateWithPidSpec)CFBundleGetFunctionPointerForName(launch_services_bundle, CFSTR("_LSASNCreateWithPid"));
 	if (!LSASNCreateWithPid)
 		return false;
 
-	kLSDisplayNameKey = *(CFStringRef*)CFBundleGetDataPointerForName(launch_services_bundle, RDSymbolNameStr(kLSDisplayNameKey));
+	kLSDisplayNameKey = *(CFStringRef*)CFBundleGetDataPointerForName(launch_services_bundle, CFSTR("_kLSDisplayNameKey"));
 	if (!kLSDisplayNameKey)
 		return false;
 
-	kLSPIDKey = *(CFStringRef*)CFBundleGetDataPointerForName(launch_services_bundle, RDSymbolNameStr(kLSPIDKey));
+	kLSPIDKey = *(CFStringRef*)CFBundleGetDataPointerForName(launch_services_bundle, CFSTR("_kLSPIDKey"));
 	if (!kLSPIDKey)
 		return false;
 
 	return true;
 }
 
-bool LaunchServicesGetProcessName(pid_t pid, std::string& result) {
+static bool LaunchServicesGetProcessName(pid_t pid, std::string& result) {
 	if (!LSCopyApplicationInformation || !LSASNCreateWithPid)
-		if (!FindLaunchServicesPrivateSymbols())
+		if (!GetLaunchServicesPrivateSymbols())
 			return false;
 
 	CFTypeRef asn = LSASNCreateWithPid(kCFAllocatorDefault, pid);
@@ -82,5 +86,92 @@
 
 	return true;
 }
+#endif // HAVE_COREFOUNDATION
+
+static bool GetProcessArgs(pid_t pid, std::string& args) {
+	/* sysctl shouldn't touch these, so we define them as const */
+	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 */
+	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);
+}
+
+static bool GetProcessNameFromArgs(pid_t pid, std::string& result) {
+	if (!GetProcessArgs(pid, result))
+		return false;
+
+	/* Get argc using memcpy */
+	int argc;
+	memcpy(&argc, &args.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));
+	if (null_pos == std::string::npos)
+		return false;
+
+	/* Find the last slash */
+	size_t last_slash = args.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);
+	return true;
+}
+
+static bool GetProcessNameFromKernel(pid_t pid, std::string& result) {
+	result.reserve(2*MAXCOMLEN);
+	if (!proc_name(pid, &result.front(), result.length()))
+		return false;
+
+	result.shrink_to_fit();
+	return true;
+}
+
+static bool GetProcessName(pid_t pid, std::string& result) {
+#ifdef HAVE_COREFOUNDATION
+	if (LaunchServicesGetProcessName(pid, result))
+		return true;
+#endif // HAVE_COREFOUNDATION
+
+	/* 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))
+		return true;
+
+	return false;
+}
 
 }
--- a/dep/animia/src/win/quartz.mm	Fri Nov 17 16:49:57 2023 -0500
+++ b/dep/animia/src/win/quartz.mm	Sat Nov 18 00:47:40 2023 -0500
@@ -1,9 +1,9 @@
 #include "animia/win/quartz.h"
 #include "animia.h"
 
-#include <Foundation/Foundation.h>
-#include <CoreGraphics/CoreGraphics.h>
-#include <AppKit/AppKit.h>
+#import <Foundation/Foundation.h>
+#import <CoreGraphics/CoreGraphics.h>
+#import <AppKit/AppKit.h>
 
 namespace animia::internal::quartz {
 
@@ -48,6 +48,8 @@
 		{
 			IntegerFromNSNumber([window objectForKey:@"kCGWindowOwnerPID"], proc.pid);
 			StringFromNSString([window objectForKey:@"kCGWindowOwnerName"], proc.name);
+			if (proc.name.empty())
+				osx::util::GetProcessName(proc.pid, proc.name);
 		}
 
 		Window win;