Я могу ответить только на первую часть вашего вопроса: чтобы определить необходимое количество выделений для списка процессов, вы должны разрешить вызов crgetproclist()
с аргументом NULL (точно так же, как sysctl()
может быть вызывается с аргументом NULL для oldp
, чтобы получить необходимый размер буфера):
int crgetproclist(struct kinfo_proc *proc_list, size_t *count) {
int err = 0;
size_t length;
static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
if (proc_list == NULL) {
// Call sysctl with a NULL buffer to get proper length
length = 0;
err = sysctl((int *)name, (sizeof(name) / sizeof(*name)), NULL, &length, NULL, 0);
} else {
// Get the actual process list
length = *count * sizeof(struct kinfo_proc);
err = sysctl((int *)name, (sizeof(name) / sizeof(*name)), proc_list, &length, NULL, 0);
}
if (err) return -1;
*count = length / sizeof(struct kinfo_proc);
return 1;
}
Теперь вы можете вызвать эту функцию из Swift дважды: сначала для определения счетчика выделения, а затем еще раз для получения процесса list:
var count: size_t = 0
crgetproclist(nil, &count)
let procList = UnsafeMutablePointer<kinfo_proc>.allocate(capacity: count)
if crgetproclist(procList, &count) == 1 {
for i in 0..<count {
let proc = procList[i]
// ...
}
}
procList.deallocate()
Обратите внимание, что вы можете легко реализовать функцию в чистом Swift:
func getProcessList() -> [kinfo_proc]? {
var name : [Int32] = [ CTL_KERN, KERN_PROC, KERN_PROC_ALL ]
var length = size_t()
sysctl(&name, UInt32(name.count), nil, &length, nil, 0)
let count = length / MemoryLayout<kinfo_proc>.size
var procList = Array(repeating: kinfo_proc(), count: count)
let result = sysctl(&name, UInt32(name.count), &procList, &length, nil, 0)
guard result == 0 else { return nil } // Some error ...
return Array(procList.prefix(length / MemoryLayout<kinfo_proc>.size))
}