# HG changeset patch # User paper@DavesDouble.local # Date 1700439208 18000 # Node ID 8f6f8dd2eb23bd944cca21390281981f4ecde21d # Parent e44b7c428d7caadd9b4cab860c74db581f760e76 dep/animia: finish kvm backend dep/animia: cmake: don't use kvm on unsupported systems, use private and public includes properly cmake: why are we defining target include directories twice? diff -r e44b7c428d7c -r 8f6f8dd2eb23 CMakeLists.txt --- a/CMakeLists.txt Sun Nov 19 17:30:38 2023 -0500 +++ b/CMakeLists.txt Sun Nov 19 19:13:28 2023 -0500 @@ -195,8 +195,7 @@ set_property(TARGET minori PROPERTY AUTOMOC ON) set_property(TARGET minori PROPERTY AUTORCC ON) -target_include_directories(minori PUBLIC ${CURL_INCLUDE_DIRS} PRIVATE ${INCLUDE}) -target_include_directories(minori PUBLIC ${Qt${QT_VERSION_MAJOR}Widgets_INCLUDE_DIRS}) +target_include_directories(minori PUBLIC ${Qt${QT_VERSION_MAJOR}Widgets_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} PRIVATE ${INCLUDE}) target_compile_options(minori PRIVATE -Wall -Wpedantic -Wextra -Wsuggest-override -Wold-style-cast) if(APPLE) target_compile_definitions(minori PUBLIC MACOSX) diff -r e44b7c428d7c -r 8f6f8dd2eb23 dep/animia/CMakeLists.txt --- a/dep/animia/CMakeLists.txt Sun Nov 19 17:30:38 2023 -0500 +++ b/dep/animia/CMakeLists.txt Sun Nov 19 19:13:28 2023 -0500 @@ -73,16 +73,15 @@ list(APPEND DEFINES LIBUTIL) list(APPEND SRC_FILES src/fd/libutil.cc) endif() # LIBUTIL_GOOD - elseif(LIBKVM_LIBRARY) # BSD libkvm - get_filename_component(LIBKVM_DIR ${LIBKVM_LIBRARY} DIRECTORY) + elseif(LIBKVM_LIBRARY) # OpenBSD kvm + include(CheckSymbolExists) + # Check if we can get open files by PID + check_symbol_exists(KERN_FILE_BYPID "kvm.h" HAVE_BYPID) - include(CheckLibraryExists) - check_library_exists(kvm kvm_getprocs ${LIBKVM_DIR} LIBKVM_GOOD) - - if(LIBKVM_GOOD) + if(HAVE_BYPID) list(APPEND LIBRARIES ${LIBKVM_LIBRARY}) list(APPEND DEFINES LIBKVM) - list(APPEND SRC_FILES src/fd/libkvm.cc) + list(APPEND SRC_FILES src/fd/kvm.cc) endif() # LIBUTIL_GOOD endif() # LINUX @@ -128,5 +127,5 @@ ) target_compile_definitions(animia PUBLIC ${DEFINES}) -target_include_directories(animia PRIVATE include PUBLIC ${INCLUDE_DIRS}) +target_include_directories(animia PUBLIC include PRIVATE ${INCLUDE_DIRS}) target_link_libraries(animia PUBLIC ${LIBRARIES}) diff -r e44b7c428d7c -r 8f6f8dd2eb23 dep/animia/include/animia/fd/kvm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dep/animia/include/animia/fd/kvm.h Sun Nov 19 19:13:28 2023 -0500 @@ -0,0 +1,20 @@ +#ifndef __animia__animia__fd__kvm_h +#define __animia__animia__fd__kvm_h + +#include +#include + +#include "animia/fd.h" +#include "animia/types.h" + +namespace animia::internal::kvm { + +class KvmFdTools final : public BaseFdTools { + public: + bool EnumerateOpenProcesses(process_proc_t process_proc) override; + bool EnumerateOpenFiles(const std::set& pids, open_file_proc_t open_file_proc) override; +}; + +} // namespace animia::internal::kvm + +#endif // __animia__animia__fd__kvm_h diff -r e44b7c428d7c -r 8f6f8dd2eb23 dep/animia/src/fd.cc --- a/dep/animia/src/fd.cc Sun Nov 19 17:30:38 2023 -0500 +++ b/dep/animia/src/fd.cc Sun Nov 19 19:13:28 2023 -0500 @@ -8,6 +8,8 @@ # include "animia/fd/xnu.h" #elif defined(LIBUTIL) # include "animia/fd/libutil.h" +#elif defined(LIBKVM) +# include "animia/fd/kvm.h" #endif namespace animia::internal { @@ -20,6 +22,8 @@ xnu::XnuFdTools os_fd; #elif defined(LIBUTIL) libutil::LibutilFdTools os_fd; +#elif defined(LIBKVM) +kvm::KvmFdTools os_fd; #else BaseFdTools os_fd; #endif diff -r e44b7c428d7c -r 8f6f8dd2eb23 dep/animia/src/fd/kvm.cc --- a/dep/animia/src/fd/kvm.cc Sun Nov 19 17:30:38 2023 -0500 +++ b/dep/animia/src/fd/kvm.cc Sun Nov 19 19:13:28 2023 -0500 @@ -7,128 +7,65 @@ ** NetBSD. */ +#include "animia/fd/kvm.h" +#include "animia/fd.h" +#include "animia.h" + +#include +#include +#include +#include +#include +#include +#include +#include + #include +#include + namespace animia::internal::kvm { -static bool GetFilename(kvm_t* kvm, struct vnode *vp, std::string& name) { - struct vnode vn; - if (!kvm_read(kvm, vp, &vn, sizeof(*vn))) - return 0; - - struct filestat fst; - const char* type = vfilestat(vn, &fst); - if (type == dead) +bool KvmFdTools::EnumerateOpenProcesses(process_proc_t process_proc) { + char errbuf[_POSIX2_LINE_MAX]; + kvm_t* kernel = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); + if (!kernel) return false; - for (DEVS* d = devs; d != NULL; d = d->next) { - if (d->fsid == fst->fsid && d->ino == fst->fileid) { - name = d->name; - break; - } - } + int entries = 0; + struct kinfo_proc* kinfo = kvm_getprocs(kernel, KERN_PROC_ALL, 0, &entries); + if (!kinfo) + return false; + + for (int i = 0; i < entries; i++) + if (!process_proc({kinfo[i].ki_paddr->p_pid, kinfo[i].ki_paddr->p_comm})) + return false; + + kvm_close(kernel); return true; } -static bool GetFilePath(kvm_t* kvm, fdfile_t* fp, std::string& path) { - struct file file; - fdfile_t fdfile; - - if (!kvm_read(kvm, fp, &fdfile, sizeof(fdfile))) - return false; - - if (!fdfile.ff_file) - return false; - - if (!kvm_read(fdfile.ff_file, &file, sizeof(file))) - return false; - - if (file.f_type != DTYPE_VNODE) - return false; - - return GetFilename(kvm, file.f_data, path); -} - -static bool OpenFiles(kvm_t* kvm, struct kinfo_proc* p, open_file_proc_t open_file_proc) { - if (p->proc->p_fd == 0 || p->proc->p_cwdi == 0) - return false; - - struct filedesc filed; - if (!kvm_read(kvm, p->proc->p_fd, &filed, sizeof(filed))) - return false; - - if (filed.fd_lastfile == -1) - return false; - - struct cwdinfo cwdi; - if (!kvm_read(kvm, p->proc->p_cwdi, &cwdi, sizeof(cwdi))) - return false; - - struct fdtab dt; - if (!kvm_read(kvm, filed.fd_dt, &dt, sizeof(dt))) - return false; - - /* check for corrupted files? */ - if ((unsigned)filed.fd_lastfile >= dt.dt_nfiles || filed.fd_freefile > filed.fd_lastfile + 1) - return false; - - /* open files */ - std::unique_ptr ofiles = nullptr; - { - ofiles.reset(malloc((filed.fd_lastfile + 1) * sizeof(fdfile_t*))); - if (!ofiles.get()) - return false; - } - - if (!kvm_read(kvm, &filed.fd_dt->dt_ff, ofiles.get(), filed.fd_lastfile + 1 * (sizeof(fdfile_t*)))) - return false; - - for (int i = 0; i <= filed.fd_lastfile; i++) { - if (!ofiles[i]) - continue; - std::string name; - GetFilePath(kvm, ofiles[i], name); - if (!open_file_proc(p->proc->p_pid, name)) - return false; - } - - return true; -} - -bool EnumerateOpenProcesses(process_proc_t process_proc) { +bool KvmFdTools::EnumerateOpenFiles(std::set& pids, open_file_proc_t open_file_proc) { char errbuf[_POSIX2_LINE_MAX]; - kvm_t* kernel = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); - if (!kernel) - return false; - - int entries = 0; - struct kinfo_proc* kinfo = kvm_getprocs(kernel, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &nentries); - if (!kinfo) - return false; - - for (int i = 0; i < entries; i++) - if (!process_proc({kinfo[i].p_pid, kinfo[i].p_comm})) - return false; - - return true; -} - -bool EnumerateOpenFiles(std::set& pids, open_file_proc_t open_file_proc) { - kvm_t* kernel = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); + kvm_t* kernel = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf); if (!kernel) return false; for (const auto& pid : pids) { int cnt; - struct kinfo_proc* kinfo = kvm_getprocs(kernel, KERN_PROC_PID, pid, &cnt); - if (!kinfo) + struct kinfo_file* kfile = kvm_getfiles(kernel, KERN_FILE_BYPID, pid, &cnt); + if (!kfile) return false; - for (int i = 0; i < cnt; i++) { - OpenFiles(kernel, kinfo, open_file_proc); - } + for (int i = 0; i < cnt; i++) + if (!open_file_proc({pid, kfile[i].kf_path})) + return false; } + + kvm_close(kernel); + + return true; } }