Обратите внимание, что список процессов, возвращаемый sysctl (3), является массивом struct kinfo_proc.Если вы прочитаете объявление kinfo_proc, вы увидите, что в нем есть член kp_eproc типа struct eproc, который, в свою очередь, имеет член e_ucred типа struct _ucred, который, в свою очередь, имеет член cr_uid типа uid_t, представляющий эффективный идентификатор пользователяэтот процесс.
Это означает, что вы можете использовать цепочку
.kp_eproc.e_ucred.cr_uid
для получения идентификатора эффективного пользователя.Например:
for (int i = 0; i < procCount; i++) {
printf("pid=%d, uid=%d\n",
procList[i].kp_proc.p_pid,
procList[i].kp_eproc.e_ucred.cr_uid);
}
Если вы хотите преобразовать идентификатор пользователя в имя пользователя, вы можете использовать getpwuid (3) или его реентерабельный / потокобезопасный вариант, getpwuid_r (3):
for (int i = 0; i < procCount; i++) {
struct passwd *user = getpwuid(procList[i].kp_eproc.e_ucred.cr_uid);
char *username = user ? user->pw_name : "getpwuid() failed";
printf("pid=%d, user=%s\n",
procList[i].kp_proc.p_pid,
username);
}
Вот пример программы, в которой перечислены все процессы с соответствующими им pids, эффективными uid и соответствующими именами пользователей:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <pwd.h>
int main(void) {
int err = 0;
struct kinfo_proc *proc_list = NULL;
size_t length = 0;
static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
// Call sysctl with a NULL buffer to get proper length
err = sysctl((int *)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0);
if (err) goto ERROR;
// Allocate buffer
proc_list = malloc(length);
if (!proc_list) goto ERROR;
// Get the actual process list
err = sysctl((int *)name, (sizeof(name) / sizeof(*name)) - 1, proc_list, &length, NULL, 0);
if (err) goto ERROR;
int proc_count = length / sizeof(struct kinfo_proc);
// use getpwuid_r() if you want to be thread-safe
for (int i = 0; i < proc_count; i++) {
uid_t uid = proc_list[i].kp_eproc.e_ucred.cr_uid;
struct passwd *user = getpwuid(uid);
char *username = user ? user->pw_name : "user name not found";
printf("pid=%d, uid=%d, username=%s\n",
proc_list[i].kp_proc.p_pid,
uid,
username);
}
free(proc_list);
return EXIT_SUCCESS;
ERROR:
perror(NULL);
free(proc_list);
return EXIT_FAILURE;
}