Mercurial > minori
comparison dep/animia/src/bsd.cpp @ 62:4c6dd5999b39
*: update
1. updated animia
2. use widestrings for filesystem on Windows
| author | Paper <mrpapersonic@gmail.com> |
|---|---|
| date | Sun, 01 Oct 2023 06:16:06 -0400 |
| parents | 6ff7aabeb9d7 |
| children | 1ce00c1c8ddc |
comparison
equal
deleted
inserted
replaced
| 61:327568ad9be9 | 62:4c6dd5999b39 |
|---|---|
| 1 /** | 1 /** |
| 2 * bsd.cpp | 2 * bsd.cpp |
| 3 * - provides support for most* versions of BSD | 3 * - provides support for most* versions of BSD |
| 4 * - this *should* also work for OS X | 4 * - this also works for OS X :) |
| 5 * more technical details: this is essentially a wrapper | 5 * more technical details: this is essentially a wrapper |
| 6 * around the very C-like BSD system functions that are... | 6 * around the very C-like BSD system functions that are... |
| 7 * kind of unnatural to use in modern C++. | 7 * kind of unnatural to use in modern C++. |
| 8 **/ | 8 **/ |
| 9 #include <vector> | |
| 10 #include <string> | |
| 11 #include <unordered_map> | |
| 12 #include <sys/types.h> | |
| 13 #include <sys/sysctl.h> | |
| 14 #include <sys/user.h> | |
| 15 #include <fcntl.h> | 9 #include <fcntl.h> |
| 16 #include <iostream> | 10 #include <iostream> |
| 11 #include <string> | |
| 12 #include <sys/sysctl.h> | |
| 13 #include <sys/types.h> | |
| 14 #include <sys/user.h> | |
| 15 #include <unordered_map> | |
| 16 #include <vector> | |
| 17 #ifdef __FreeBSD__ | 17 #ifdef __FreeBSD__ |
| 18 #include <libutil.h> | 18 # include <libutil.h> |
| 19 #elif defined(__APPLE__) | 19 #elif defined(__APPLE__) |
| 20 #include <libproc.h> | 20 # include <libproc.h> |
| 21 #endif | 21 #endif |
| 22 | 22 |
| 23 namespace Animia::Unix { | 23 namespace Animia::Unix { |
| 24 | 24 |
| 25 /* this is a cleaned up version of a function from... Apple? | 25 /* this is a cleaned up version of a function from... Apple? |
| 26 ...anyway, what it essentially does is gets the size and stuff from | 26 ...anyway, what it essentially does is gets the size and stuff from |
| 27 sysctl() and reserves the space in a vector to store the PIDs */ | 27 sysctl() and reserves the space in a vector to store the PIDs */ |
| 28 std::vector<int> get_all_pids() { | 28 std::vector<int> get_all_pids() { |
| 29 std::vector<int> ret; | 29 std::vector<int> ret; |
| 30 struct kinfo_proc* result = NULL; | 30 struct kinfo_proc* result = NULL; |
| 31 size_t length = 0; | 31 size_t length = 0; |
| 32 static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 }; | 32 static const int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; |
| 33 | 33 |
| 34 /* get appropriate length from sysctl() */ | 34 /* get appropriate length from sysctl() |
| 35 sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0); | 35 note: the reason this isn't checked is actually because this will |
| 36 *always* return an error on OS X (or... maybe I'm doing it wrong :) ) */ | |
| 37 sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0); | |
| 36 | 38 |
| 37 result = (struct kinfo_proc*)malloc(length); | 39 result = (struct kinfo_proc*)malloc(length); |
| 38 if (result == NULL) | 40 if (result == NULL) |
| 39 return std::vector<int>(); | 41 return std::vector<int>(); |
| 40 | 42 |
| 41 /* actually get our results */ | 43 /* actually get our results */ |
| 42 if (sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0) == ENOMEM) { | 44 if (sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0) == ENOMEM) { |
| 43 assert(result != NULL); | 45 assert(result != NULL); |
| 44 free(result); | 46 free(result); |
| 45 throw std::bad_alloc(); | 47 throw std::bad_alloc(); |
| 46 } | 48 } |
| 47 | 49 |
| 48 /* add pids to our vector */ | 50 /* add pids to our vector */ |
| 49 ret.reserve(length/sizeof(*result)); | 51 ret.reserve(length / sizeof(*result)); |
| 50 for (int i = 0; i < length/sizeof(*result); i++) | 52 for (int i = 0; i < length / sizeof(*result); i++) |
| 51 ret.push_back(result[i].kp_proc.p_pid); | 53 ret.push_back(result[i].kp_proc.p_pid); |
| 52 | 54 |
| 53 return ret; | 55 return ret; |
| 54 } | 56 } |
| 55 | 57 |
| 56 std::string get_process_name(int pid) { | 58 std::string get_process_name(int pid) { |
| 57 std::string ret; | 59 std::string ret; |
| 58 #ifdef __FreeBSD__ | 60 #ifdef __FreeBSD__ |
| 59 struct kinfo_proc* proc = kinfo_getproc(pid); | 61 struct kinfo_proc* proc = kinfo_getproc(pid); |
| 60 if (!proc) { | 62 if (!proc) |
| 61 return ""; | 63 return ""; |
| 62 ret = proc->ki_comm; | 64 ret = proc->ki_comm; |
| 63 free(proc); | 65 free(proc); |
| 64 #elif defined(__APPLE__) | 66 #elif defined(__APPLE__) |
| 65 struct proc_bsdinfo proc; | 67 struct proc_bsdinfo proc; |
| 66 | 68 |
| 67 int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE); | 69 int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE); |
| 68 if (st != PROC_PIDTBSDINFO_SIZE) | 70 if (st != PROC_PIDTBSDINFO_SIZE) |
| 69 return ""; | 71 return ""; |
| 70 return proc.pbi_comm; | 72 ret = proc.pbi_comm; |
| 71 #endif | 73 #endif |
| 72 return ret; | 74 return ret; |
| 73 } | 75 } |
| 74 | 76 |
| 75 std::vector<std::string> get_open_files(int pid) { | 77 std::vector<std::string> get_open_files(int pid) { |
| 76 // initialize buffer | 78 /* note: this is OS X only right now. eventually, I'll find a way |
| 77 std::vector<std::string> ret; | 79 to do this in FreeBSD, OpenBSD and the like */ |
| 78 int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); | 80 std::vector<std::string> ret; |
| 79 struct proc_fdinfo *info = (struct proc_fdinfo *)malloc(bufsz); | 81 int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); |
| 80 proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info, bufsz); | 82 struct proc_fdinfo* info = (struct proc_fdinfo*)malloc(bufsz); |
| 83 proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info, bufsz); | |
| 81 | 84 |
| 82 // iterate over stuff | 85 // iterate over stuff |
| 83 for (int i = 0; i < bufsz/sizeof(info[0]); i++) { | 86 ret.reserve(bufsz / sizeof(info[0])); |
| 84 if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) { | 87 for (int i = 0; i < bufsz / sizeof(info[0]); i++) { |
| 85 struct vnode_fdinfowithpath vnodeInfo; | 88 if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) { |
| 86 proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, PROC_PIDFDVNODEPATHINFO_SIZE); | 89 struct vnode_fdinfowithpath vnodeInfo; |
| 87 ret.push_back(vnodeInfo.pvip.vip_path); | 90 proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, PROC_PIDFDVNODEPATHINFO_SIZE); |
| 88 } | 91 ret.push_back(vnodeInfo.pvip.vip_path); |
| 89 } | 92 } |
| 90 return ret; | 93 } |
| 94 return ret; | |
| 91 } | 95 } |
| 92 | 96 |
| 93 std::unordered_map<int, std::vector<std::string>> get_all_open_files() { | 97 std::unordered_map<int, std::vector<std::string>> get_all_open_files() { |
| 94 std::unordered_map<int, std::vector<std::string>> map; | 98 std::unordered_map<int, std::vector<std::string>> map; |
| 95 std::vector<int> pids = get_all_pids(); | 99 std::vector<int> pids = get_all_pids(); |
| 96 for (int i: pids) { | 100 for (int i : pids) { |
| 97 map[i] = get_open_files(i); | 101 map[i] = get_open_files(i); |
| 98 } | 102 } |
| 99 return map; | 103 return map; |
| 100 } | 104 } |
| 101 | 105 |
| 102 } | 106 } // namespace Animia::Unix |
