Mercurial > minori
comparison dep/animia/src/platform/bsd/fd.cc @ 137:69db40272acd
dep/animia: [WIP] huge refactor
this WILL NOT compile, because lots of code has been changed
and every API in the original codebase has been removed.
note that this api setup is not exactly permanent...
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Fri, 10 Nov 2023 13:52:47 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
136:7d3ad9529c4c | 137:69db40272acd |
---|---|
1 /** | |
2 * bsd.cpp | |
3 * - provides support for most* versions of BSD | |
4 * - this also works for OS X :) | |
5 * more technical details: this is essentially a wrapper | |
6 * around the very C-like BSD system functions that are... | |
7 * kind of unnatural to use in modern C++. | |
8 **/ | |
9 #include <fcntl.h> | |
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__ | |
18 # include <libutil.h> | |
19 #elif defined(__APPLE__) | |
20 # include <libproc.h> | |
21 #endif | |
22 | |
23 namespace Animia { namespace Unix { | |
24 | |
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 | |
27 sysctl() and reserves the space in a vector to store the PIDs */ | |
28 std::vector<int> get_all_pids() { | |
29 std::vector<int> ret; | |
30 struct kinfo_proc* result = NULL; | |
31 size_t length = 0; | |
32 static const int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; | |
33 | |
34 /* get appropriate length from sysctl() | |
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); | |
38 | |
39 result = (struct kinfo_proc*)malloc(length); | |
40 if (result == NULL) | |
41 return std::vector<int>(); | |
42 | |
43 /* actually get our results */ | |
44 if (sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0) == ENOMEM) { | |
45 assert(result != NULL); | |
46 free(result); | |
47 throw std::bad_alloc(); | |
48 } | |
49 | |
50 /* add pids to our vector */ | |
51 ret.reserve(length / sizeof(*result)); | |
52 for (int i = 0; i < length / sizeof(*result); i++) | |
53 ret.push_back(result[i].kp_proc.p_pid); | |
54 | |
55 return ret; | |
56 } | |
57 | |
58 std::string get_process_name(int pid) { | |
59 std::string ret; | |
60 #ifdef __FreeBSD__ | |
61 struct kinfo_proc* proc = kinfo_getproc(pid); | |
62 if (!proc) | |
63 return ""; | |
64 ret = proc->ki_comm; | |
65 free(proc); | |
66 #elif defined(__APPLE__) | |
67 struct proc_bsdinfo proc; | |
68 | |
69 int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE); | |
70 if (st != PROC_PIDTBSDINFO_SIZE) | |
71 return ""; | |
72 ret = proc.pbi_comm; | |
73 #endif | |
74 return ret; | |
75 } | |
76 | |
77 std::vector<std::string> get_open_files(int pid) { | |
78 /* note: this is OS X only right now. eventually, I'll find a way | |
79 to do this in FreeBSD, OpenBSD and the like */ | |
80 std::vector<std::string> ret; | |
81 | |
82 if (pid == 0) | |
83 return ret; | |
84 | |
85 int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); | |
86 if (bufsz == -1) | |
87 return ret; | |
88 | |
89 struct proc_fdinfo* info = (struct proc_fdinfo*)malloc(bufsz); | |
90 if (!info) | |
91 return ret; | |
92 | |
93 proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info, bufsz); | |
94 | |
95 // iterate over stuff | |
96 ret.reserve(bufsz / sizeof(info[0])); | |
97 for (int i = 0; i < bufsz / sizeof(info[0]); i++) { | |
98 if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) { | |
99 struct vnode_fdinfowithpath vnodeInfo; | |
100 | |
101 int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, PROC_PIDFDVNODEPATHINFO_SIZE); | |
102 if (sz != PROC_PIDFDVNODEPATHINFO_SIZE) | |
103 continue; | |
104 | |
105 if (vnodeInfo.pfi.fi_openflags & O_WRONLY || vnodeInfo.pfi.fi_openflags & O_RDWR) | |
106 continue; | |
107 | |
108 ret.push_back(vnodeInfo.pvip.vip_path); | |
109 } | |
110 } | |
111 return ret; | |
112 } | |
113 | |
114 std::unordered_map<int, std::vector<std::string>> get_all_open_files() { | |
115 std::unordered_map<int, std::vector<std::string>> map; | |
116 std::vector<int> pids = get_all_pids(); | |
117 for (int i : pids) { | |
118 map[i] = get_open_files(i); | |
119 } | |
120 return map; | |
121 } | |
122 | |
123 } // namespace Unix | |
124 } // namespace Animia |