Mercurial > minori
view dep/animia/src/fd/kvm.cc @ 191:0fc126d52de4
animia: multiple stylistic choices
win.class_name is now used to store bundle IDs on OS X,
add some little explanations here and there for dumb stuff
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Thu, 07 Dec 2023 01:48:04 -0500 |
parents | e44b7c428d7c |
children | 8f6f8dd2eb23 |
line wrap: on
line source
/* kvm.cc: provides support for libkvm in multiple BSDs ** ** this is really the only way to get a thing that works on ** OpenBSD AND NetBSD. ** ** Much of this file is taken from the fstat source code in ** NetBSD. */ #include <kvm.h> 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) return false; for (DEVS* d = devs; d != NULL; d = d->next) { if (d->fsid == fst->fsid && d->ino == fst->fileid) { name = d->name; break; } } 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<fdfile_t*[]> 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) { 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<pid_t>& pids, open_file_proc_t open_file_proc) { kvm_t* kernel = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, 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) return false; for (int i = 0; i < cnt; i++) { OpenFiles(kernel, kinfo, open_file_proc); } } } }