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 |