Mercurial > minori
changeset 153:bd439dd6ffc5
*: make win stuff actually work, rename bsd.cc to xnu.cc
It's been OS X only for ages, and these functions are different between
most BSDs anyway
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Wed, 15 Nov 2023 13:28:18 -0500 |
parents | 8700806c2cc2 |
children | d43d68408d3c |
files | dep/animia/CMakeLists.txt dep/animia/include/animia/fd/bsd.h dep/animia/include/animia/fd/xnu.h dep/animia/include/animia/player.h dep/animia/src/animia.cc dep/animia/src/fd.cc dep/animia/src/fd/bsd.cc dep/animia/src/fd/xnu.cc dep/animia/src/strategist.cc dep/animia/src/util.cc dep/animia/src/win/win32.cc src/track/media.cc |
diffstat | 12 files changed, 154 insertions(+), 195 deletions(-) [+] |
line wrap: on
line diff
--- a/dep/animia/CMakeLists.txt Wed Nov 15 02:34:59 2023 -0500 +++ b/dep/animia/CMakeLists.txt Wed Nov 15 13:28:18 2023 -0500 @@ -15,10 +15,10 @@ # linux src/fd/linux.cc ) -elseif(UNIX) # this won't run on Linux +elseif(MACOSX) # this won't run on Linux list(APPEND SRC_FILES - # bsd - src/fd/bsd.cc + # xnu stuff + src/fd/xnu.cc ) elseif(WIN32) list(APPEND SRC_FILES
--- a/dep/animia/include/animia/fd/bsd.h Wed Nov 15 02:34:59 2023 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -#ifndef __animia__animia__fd__linux_h -#define __animia__animia__fd__linux_h - -#include <string> -#include <set> - -#include "animia/types.h" -#include "animia/fd.h" - -#ifdef unix -#undef unix -#endif - -namespace animia::internal::unix { - -class UnixFdTools final : public BaseFdTools { - public: - bool EnumerateOpenProcesses(process_proc_t process_proc) override; - bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) override; -}; - -} - -#endif // __animia__animia__fd__linux_h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dep/animia/include/animia/fd/xnu.h Wed Nov 15 13:28:18 2023 -0500 @@ -0,0 +1,20 @@ +#ifndef __animia__animia__fd__xnu_h +#define __animia__animia__fd__xnu_h + +#include <string> +#include <set> + +#include "animia/types.h" +#include "animia/fd.h" + +namespace animia::internal::xnu { + +class XnuFdTools final : public BaseFdTools { + public: + bool EnumerateOpenProcesses(process_proc_t process_proc) override; + bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) override; +}; + +} + +#endif // __animia__animia__fd__xnu_h
--- a/dep/animia/include/animia/player.h Wed Nov 15 02:34:59 2023 -0500 +++ b/dep/animia/include/animia/player.h Wed Nov 15 13:28:18 2023 -0500 @@ -7,7 +7,7 @@ namespace animia { enum class Strategy { - WindowTitle, // unused + WindowTitle, OpenFiles, UiAutomation // unused };
--- a/dep/animia/src/animia.cc Wed Nov 15 02:34:59 2023 -0500 +++ b/dep/animia/src/animia.cc Wed Nov 15 13:28:18 2023 -0500 @@ -38,10 +38,10 @@ } static bool PlayerHasStrategy(const Player& player, const Strategy& strategy) { - for (const auto& pstrategy : player.strategies) { + for (const auto& pstrategy : player.strategies) if (pstrategy == strategy) return true; - } + return false; }
--- a/dep/animia/src/fd.cc Wed Nov 15 02:34:59 2023 -0500 +++ b/dep/animia/src/fd.cc Wed Nov 15 13:28:18 2023 -0500 @@ -4,8 +4,8 @@ # include "animia/fd/win32.h" #elif defined(LINUX) # include "animia/fd/linux.h" -#elif defined(UNIX) -# include "animia/fd/bsd.h" +#elif defined(MACOSX) +# include "animia/fd/xnu.h" #endif namespace animia::internal { @@ -14,8 +14,8 @@ win32::Win32FdTools os_fd; #elif defined(LINUX) linux::LinuxFdTools os_fd; -#elif defined(UNIX) -unix::UnixFdTools os_fd; +#elif defined(MACOSX) +xnu::XnuFdTools os_fd; #else BaseFdTools os_fd; #endif
--- a/dep/animia/src/fd/bsd.cc Wed Nov 15 02:34:59 2023 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,124 +0,0 @@ -/* -** fd/bsd.cpp -** - this ONLY* supports OS X as of now -** (*there is some FreeBSD support code) -*/ -#include "animia/fd/bsd.h" -#include "animia.h" - -#include <unordered_map> -#include <vector> -#include <string> - -#include <fcntl.h> -#include <sys/sysctl.h> -#include <sys/types.h> -#include <sys/user.h> - -#ifdef __FreeBSD__ -# include <libutil.h> -#elif defined(__APPLE__) -# include <libproc.h> -#endif - -namespace animia::internal::unix { - -static bool GetProcessName(pid_t pid, std::string& result) { -#ifdef __FreeBSD__ - struct kinfo_proc* proc = kinfo_getproc(pid); - if (!proc) - return false; - result = proc->ki_comm; - - /* FreeBSD manpage for kinfo_getproc(): - "The pointer was obtained by an internal call to malloc(3) and - must be freed by the caller with a call to free(3)." */ - free(proc); - - return true; -#elif defined(__APPLE__) - struct proc_bsdinfo proc; - - int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE); - if (st != PROC_PIDTBSDINFO_SIZE) - return false; - - /* fixme: is this right? pbi_comm is an alternative, but it reduces the string size to - 16 chars. does pbi_name do the same, or is it different? */ - result = proc.pbi_name; - return true; -#endif -} - -/* this is a cleaned up version of a function from... Apple? - ...anyway, what it essentially does is gets the size and stuff from - sysctl() and reserves the space in a vector to store the PIDs - - TODO: https://kaashif.co.uk/2015/06/18/how-to-get-a-list-of-processes-on-openbsd-in-c/ */ -bool UnixFdTools::EnumerateOpenProcesses(process_proc_t process_proc) { - struct kinfo_proc* result = NULL; - size_t length = 0; - static const int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; - - /* get appropriate length from sysctl() - note: the reason this isn't checked is actually because this will - *always* return an error on OS X (or... maybe I'm doing it wrong :) ) */ - sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0); - - result = (struct kinfo_proc*)malloc(length); - if (result == NULL) - return std::vector<int>(); - - /* TODO: this might actually return ENOMEM if the amount of file handles changes between the - original sysctl() call and this one, which is technically possible */ - if (sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0) == ENOMEM) { - assert(result != NULL); - free(result); - throw std::bad_alloc(); - } - - for (int i = 0; i < length / sizeof(*result); i++) { - const pid_t pid = result[i].kp_proc.p_pid; - if (!process_proc({pid, GetProcessName(pid)})) - return false; - } -} - -/* this only works on OS X :( */ -bool UnixFdTools::EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) { - if (!open_file_proc) - return false; - - for (const auto& pid : pids) { - int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); - if (bufsz == -1) - return false; - - struct proc_fdinfo* info = (struct proc_fdinfo*)malloc(bufsz); - if (!info) - return false; - - proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info, bufsz); - - for (int i = 0; i < bufsz / sizeof(info[0]); i++) { - if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) { - struct vnode_fdinfowithpath vnodeInfo; - - int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, PROC_PIDFDVNODEPATHINFO_SIZE); - if (sz != PROC_PIDFDVNODEPATHINFO_SIZE) - return false; - - /* this doesn't work! - if (vnodeInfo.pfi.fi_openflags & O_WRONLY || vnodeInfo.pfi.fi_openflags & O_RDWR) - continue; - */ - - if (!open_file_proc({pid, vnodeInfo.pvip.vip_path})) - return false; - } - } - } - return true; -} - -} // namespace animia::internal::unix
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dep/animia/src/fd/xnu.cc Wed Nov 15 13:28:18 2023 -0500 @@ -0,0 +1,101 @@ +/* +** fd/xnu.cpp +** - provides support for XNU (part of Darwin) +*/ +#include "animia/fd/xnu.h" +#include "animia.h" + +#include <unordered_map> +#include <vector> +#include <string> + +#include <fcntl.h> +#include <sys/sysctl.h> +#include <sys/types.h> +#include <sys/user.h> +#include <libproc.h> + +namespace animia::internal::xnu { + +static bool GetProcessName(pid_t pid, std::string& result) { + struct proc_bsdinfo proc; + + int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE); + if (st != PROC_PIDTBSDINFO_SIZE) + return false; + + /* fixme: is this right? pbi_comm is an alternative, but it reduces the string size to + 16 chars. does pbi_name do the same, or is it different? */ + result = proc.pbi_name; + return true; +} + +/* this is a cleaned up version of a function from... Apple? + ...anyway, what it essentially does is gets the size and stuff from + sysctl() and reserves the space in a vector to store the PIDs */ +bool XnuFdTools::EnumerateOpenProcesses(process_proc_t process_proc) { + struct kinfo_proc* result = NULL; + size_t length = 0; + static const int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; + + /* get appropriate length from sysctl() + note: the reason this isn't checked is actually because this will + *always* return an error on OS X (or... maybe I'm doing it wrong :) ) */ + sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0); + + result = (struct kinfo_proc*)malloc(length); + if (result == NULL) + return false; + + /* TODO: this might actually return ENOMEM if the amount of file handles changes between the + original sysctl() call and this one, which is technically possible */ + if (sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0) == ENOMEM) { + assert(result != NULL); + free(result); + return false; + } + + for (int i = 0; i < length / sizeof(*result); i++) { + const pid_t pid = result[i].kp_proc.p_pid; + if (!process_proc({pid, GetProcessName(pid)})) + return false; + } +} + +bool XnuFdTools::EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) { + if (!open_file_proc) + return false; + + for (const auto& pid : pids) { + int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); + if (bufsz == -1) + return false; + + struct proc_fdinfo* info = (struct proc_fdinfo*)malloc(bufsz); + if (!info) + return false; + + proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info, bufsz); + + for (int i = 0; i < bufsz / sizeof(info[0]); i++) { + if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) { + struct vnode_fdinfowithpath vnodeInfo; + + int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, PROC_PIDFDVNODEPATHINFO_SIZE); + if (sz != PROC_PIDFDVNODEPATHINFO_SIZE) + return false; + + /* this doesn't work! + if (vnodeInfo.pfi.fi_openflags & O_WRONLY || vnodeInfo.pfi.fi_openflags & O_RDWR) + continue; + */ + + if (!open_file_proc({pid, vnodeInfo.pvip.vip_path})) + return false; + } + } + } + return true; +} + +} // namespace animia::internal::unix
--- a/dep/animia/src/strategist.cc Wed Nov 15 02:34:59 2023 -0500 +++ b/dep/animia/src/strategist.cc Wed Nov 15 13:28:18 2023 -0500 @@ -32,7 +32,6 @@ success |= ApplyOpenFilesStrategy(); break; case ResultType::Window: - std::cout << "Wat" << std::endl; success |= ApplyWindowTitleStrategy(); break; }
--- a/dep/animia/src/util.cc Wed Nov 15 02:34:59 2023 -0500 +++ b/dep/animia/src/util.cc Wed Nov 15 13:28:18 2023 -0500 @@ -2,7 +2,6 @@ #include <fstream> #include <sstream> #include <string> -#include <cctype> #include <regex> #include <iostream> @@ -27,12 +26,17 @@ return true; } +/* this assumes ASCII... which really should be the case for what we need, anyway */ bool EqualStrings(const std::string& str1, const std::string& str2) { - auto equal_chars = [](const char c1, const char c2) -> bool { - return std::tolower(static_cast<unsigned char>(c1)) == std::tolower(static_cast<unsigned char>(c2)); + auto tolower = [](const char c) -> char { + return ('A' <= c && c <= 'Z') ? c + ('a' - 'A') : c; }; - return str1.size() == str2.size() && std::equal(str1.begin(), str1.end(), str2.begin(), equal_chars); + auto equal_chars = [&tolower](const char c1, const char c2) -> bool { + return tolower(c1) == tolower(c2); + }; + + return str1.length() == str2.length() && std::equal(str1.begin(), str1.end(), str2.begin(), equal_chars); } bool Stem(const std::string& filename, std::string& stem) {
--- a/dep/animia/src/win/win32.cc Wed Nov 15 02:34:59 2023 -0500 +++ b/dep/animia/src/win/win32.cc Wed Nov 15 13:28:18 2023 -0500 @@ -17,14 +17,21 @@ std::wstring buffer(kMaxSize, L'\0'); const auto size = ::GetClassNameW(hwnd, &buffer.front(), buffer.length()); + /* for some reason GetClassName returns the actual size of the buffer *with* the + terminating NULL byte */ + buffer.resize(size); return buffer; } static std::wstring GetWindowText(HWND hwnd) { - const int size = ::GetWindowTextLengthW(hwnd); + const int estimated_size = ::GetWindowTextLengthW(hwnd); - std::wstring buffer(size, L'\0'); - ::GetWindowTextW(hwnd, &buffer.front(), buffer.length()); + std::wstring buffer(estimated_size + 1, L'\0'); + const auto size = ::GetWindowTextW(hwnd, &buffer.front(), buffer.length()); + /* GetWindowTextLength docs: + "Under certain conditions, the GetWindowTextLength function may return a value + that is larger than the actual length of the text." */ + buffer.resize(size); return buffer; } @@ -55,7 +62,8 @@ if (!::QueryFullProcessImageNameW(process_handle.get(), 0, &buffer.front(), &buf_size)) return std::wstring(); - return buffer.substr(0, buf_size + 1); + buffer.resize(buf_size); + return buffer; } ////////////////////////////////////////////////////////////////////////////////
--- a/src/track/media.cc Wed Nov 15 02:34:59 2023 -0500 +++ b/src/track/media.cc Wed Nov 15 13:28:18 2023 -0500 @@ -41,6 +41,9 @@ for (const auto& result : results) { for (const auto& media : result.media) { for (const auto& info : media.information) { + switch (info.type) { + case + } std::cout << static_cast<int>(info.type) << ": " << info.value << std::endl; vec.push_back(info.value); success |= true; @@ -51,33 +54,5 @@ return success; } -/* this sucks. use anitomy directly like a real man */ -std::unordered_map<std::string, std::string> GetMapFromElements(const anitomy::Elements& elements) { - std::unordered_map<std::string, std::string> ret; - - ret["title"] = Strings::ToUtf8String(elements.get(anitomy::kElementAnimeTitle)); - ret["filename"] = Strings::ToUtf8String(elements.get(anitomy::kElementFileName)); - ret["language"] = Strings::ToUtf8String(elements.get(anitomy::kElementLanguage)); - ret["group"] = Strings::ToUtf8String(elements.get(anitomy::kElementReleaseGroup)); - ret["episode"] = Strings::ToUtf8String(elements.get(anitomy::kElementEpisodeNumber)); - ret["resolution"] = Strings::ToUtf8String(elements.get(anitomy::kElementVideoResolution)); - - return ret; -} - -std::unordered_map<std::string, std::string> GetFileElements(const std::string& basename) { - anitomy::Anitomy anitomy; - anitomy.Parse(Strings::ToWstring(basename)); - - return GetMapFromElements(anitomy.elements()); -} - -std::unordered_map<std::string, std::string> GetFileElements(const std::filesystem::path& path) { - anitomy::Anitomy anitomy; - anitomy.Parse(path.filename().wstring()); - - return GetMapFromElements(anitomy.elements()); -} - } // namespace Media } // namespace Track