comparison dep/animia/src/fd/xnu.cc @ 163:44c5e6dd9488

dep/animia/osx: move GetProcessName to util/osx so we can use it in quartz
author Paper <mrpapersonic@gmail.com>
date Sat, 18 Nov 2023 00:47:40 -0500
parents 61b76c7b656a
children 54c5d80a737e
comparison
equal deleted inserted replaced
162:61b76c7b656a 163:44c5e6dd9488
22 22
23 #include <iostream> 23 #include <iostream>
24 24
25 namespace animia::internal::xnu { 25 namespace animia::internal::xnu {
26 26
27 static bool GetProcessNameFromArgs(pid_t pid, std::string& result) {
28 /* sysctl shouldn't touch these, so we define them as const */
29 const int mib[3] = {CTL_KERN, KERN_PROCARGS2, static_cast<int>(pid)};
30 const size_t mib_size = sizeof(mib)/sizeof(*mib);
31
32 /* Get the initial size of the array */
33 size_t size;
34 {
35 int ret = sysctl((int*)mib, mib_size, nullptr, &size, nullptr, 0);
36 if (ret)
37 return false;
38 }
39
40 /* Reserve the space for it in a std::string */
41 std::string args;
42 args.resize(size);
43
44 /* Get the contents of argc and argv */
45 {
46 int ret = sysctl((int*)mib, mib_size, &args.front(), &size, NULL, 0);
47 if (ret)
48 return false;
49 }
50
51 /* Is the size big enough to hold at least argc? */
52 if (size < sizeof(int))
53 return false;
54
55 args.resize(size);
56
57 /* Get argc using memcpy */
58 int argc;
59 memcpy(&argc, &args.front(), sizeof(argc));
60
61 /* Do we even have argv[0]? */
62 if (argc < 1)
63 return false;
64
65 /* Find the first null character */
66 size_t null_pos = args.find('\0', sizeof(argc));
67 if (null_pos == std::string::npos)
68 return false;
69
70 /* Find the last slash */
71 size_t last_slash = args.rfind('/', null_pos);
72 if (last_slash == std::string::npos)
73 return false;
74
75 /* Return our result */
76 result = args.substr(last_slash + 1, null_pos - last_slash - 1);
77 return true;
78 }
79
80 static bool GetProcessNameFromKernel(pid_t pid, std::string& result) {
81 result.reserve(2*MAXCOMLEN);
82 if (!proc_name(pid, &result.front(), result.length()))
83 return false;
84
85 result.shrink_to_fit();
86 return true;
87 }
88
89 static bool GetProcessName(pid_t pid, std::string& result) {
90 /* Use LaunchServices */
91 #ifdef HAVE_COREFOUNDATION
92 if (osx::util::LaunchServicesGetProcessName(pid, result))
93 return true;
94 #endif
95
96 /* Try parsing the arguments, this prevents the process name being
97 cut off to 2*MAXCOMLEN (32 chars) */
98 if (GetProcessNameFromArgs(pid, result))
99 return true;
100
101 /* Then attempt getting it from the kernel, which results in the process name
102 being cut to 32 chars (16 chars if p_name is unavailable) */
103 if (GetProcessNameFromKernel(pid, result))
104 return true;
105
106 return false;
107 }
108
109 bool XnuFdTools::EnumerateOpenProcesses(process_proc_t process_proc) { 27 bool XnuFdTools::EnumerateOpenProcesses(process_proc_t process_proc) {
110 size_t pids_size = 512; 28 size_t pids_size = 512;
111 std::unique_ptr<pid_t[]> pids; 29 std::unique_ptr<pid_t[]> pids;
112 30
113 int returned_size = 0; 31 int returned_size = 0;
118 return false; 36 return false;
119 } while ((pids_size * sizeof(size_t)) < returned_size); 37 } while ((pids_size * sizeof(size_t)) < returned_size);
120 38
121 for (int i = 0; i < pids_size; i++) { 39 for (int i = 0; i < pids_size; i++) {
122 std::string result; 40 std::string result;
123 GetProcessName(pids[i], result); 41 osx::util::GetProcessName(pids[i], result);
124 if (!process_proc({pids[i], result})) 42 if (!process_proc({pids[i], result}))
125 return false; 43 return false;
126 } 44 }
127 45
128 return true; 46 return true;