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