Mercurial > minori
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;