From 9c17a0c4d02dc8f39a2cfd440706f91133311fad Mon Sep 17 00:00:00 2001 From: Simon Sigurdhsson Date: Mon, 2 Jul 2012 01:45:28 +0200 Subject: Completed the iterator for OSX. --- src/memrchr.c | 2 - src/process_iterator.c | 2 + src/process_iterator.h | 4 +- src/process_iterator_apple.c | 146 +++++++++++++++++++++++-------------------- 4 files changed, 84 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/memrchr.c b/src/memrchr.c index 35e07de..ba788f5 100644 --- a/src/memrchr.c +++ b/src/memrchr.c @@ -15,8 +15,6 @@ */ #include -#include -#include /* * Reverse memchr() diff --git a/src/process_iterator.c b/src/process_iterator.c index 165f420..8b4019d 100644 --- a/src/process_iterator.c +++ b/src/process_iterator.c @@ -22,7 +22,9 @@ #include #include #include +#ifndef __APPLE__ #include +#endif #include #include "process_iterator.h" diff --git a/src/process_iterator.h b/src/process_iterator.h index ecbe995..70520b6 100644 --- a/src/process_iterator.h +++ b/src/process_iterator.h @@ -81,7 +81,9 @@ struct process_iterator { int count; int i; #elif defined __APPLE__ - struct kinfo_proc *proclist; + int i; + int count; + int *pidlist; #endif struct process_filter *filter; }; diff --git a/src/process_iterator_apple.c b/src/process_iterator_apple.c index d7aa5f3..1f98bf2 100644 --- a/src/process_iterator_apple.c +++ b/src/process_iterator_apple.c @@ -19,80 +19,92 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -int init_process_iterator(struct process_iterator *it) { +#include +#include +#include + +int init_process_iterator(struct process_iterator *it, struct process_filter *filter) { + it->i = 0; + /* Find out how much to allocate for it->pidlist */ + if ((it->count = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0)) <= 0) { + fprintf(stderr, "proc_listpids: %s\n", strerror(errno)); + return -1; + } + /* Allocate and populate it->pidlist */ + if ((it->pidlist = (int *)malloc((it->count)*sizeof(int))) == NULL) { + fprintf(stderr, "malloc: %s\n", strerror(errno)); + } + if ((it->count = proc_listpids(PROC_ALL_PIDS, 0, it->pidlist, it->count)) <= 0) { + fprintf(stderr, "proc_listpids: %s\n", strerror(errno)); + return -1; + } + it->filter = filter; + return 0; +} + +static int pti2proc(struct proc_taskallinfo *ti, struct process *process) { + int bytes; + process->pid = ti->pbsd.pbi_pid; + process->ppid = ti->pbsd.pbi_ppid; + process->starttime = ti->pbsd.pbi_start_tvsec; + process->cputime = ti->ptinfo.pti_total_user + ti->ptinfo.pti_total_system; + bytes = strlen(ti->pbsd.pbi_comm); + memcpy(process->command, ti->pbsd.pbi_comm, (bytes < PATH_MAX ? bytes : PATH_MAX) + 1); + return 0; +} + +static int get_process_pti(pid_t pid, struct proc_taskallinfo *ti) { + int bytes; + bytes = proc_pidinfo(pid, PROC_PIDTASKALLINFO, 0, ti, sizeof(ti)); + if (bytes <= 0) { + fprintf(stderr, "proc_pidinfo: %s\n", strerror(errno)); + return -1; + } else if (bytes < sizeof(ti)) { + fprintf(stderr, "proc_pidinfo: too few bytes; expected %ld, got %d\n", sizeof(ti), bytes); + return -1; + } return 0; } int get_next_process(struct process_iterator *it, struct process *p) { + struct proc_taskallinfo *ti = NULL; + if (it->i == it->count) return -1; + if (it->filter->pid != 0 && !it->filter->include_children) { + if (get_process_pti(it->filter->pid, ti) != 0) { + it->i = it->count = 0; + return -1; + } + it->i = it->count = 1; + return pti2proc(ti, p); + } + while (it->i < it->count) { + get_process_pti(it->pidlist[it->i], ti); + if (ti == NULL || ti->pbsd.pbi_flags & PROC_FLAG_SYSTEM) { + it->i++; + continue; + } + if (it->filter->pid != 0 && it->filter->include_children) { + pti2proc(ti, p); + it->i++; + if (p->pid != it->filter->pid && p->ppid != it->filter->pid) + continue; + return 0; + } + else if (it->filter->pid == 0) + { + pti2proc(ti, p); + it->i++; + return 0; + } + } return -1; } int close_process_iterator(struct process_iterator *it) { + free(it->pidlist); + it->pidlist = NULL; + it->filter = NULL; + it->count = 0; + it->i = 0; return 0; } - - // int err; - // struct kinfo_proc *result = NULL; - // size_t length; - // int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; - - // /* We start by calling sysctl with result == NULL and length == 0. - // That will succeed, and set length to the appropriate length. - // We then allocate a buffer of that size and call sysctl again - // with that buffer. - // */ - // length = 0; - // err = sysctl(mib, 4, NULL, &length, NULL, 0); - // if (err == -1) { - // err = errno; - // } - // if (err == 0) { - // result = malloc(length); - // err = sysctl(mib, 4, result, &length, NULL, 0); - // if (err == -1) - // err = errno; - // if (err == ENOMEM) { - // free(result); /* clean up */ - // result = NULL; - // } - // } - - // i->proclist = result; - // i->count = err == 0 ? length / sizeof *result : 0; - // i->c = 0; - -// int get_proc_info(struct process *p, pid_t pid) { -// int err; -// struct kinfo_proc *result = NULL; -// size_t length; -// int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; - -// /* We start by calling sysctl with result == NULL and length == 0. -// That will succeed, and set length to the appropriate length. -// We then allocate a buffer of that size and call sysctl again -// with that buffer. -// */ -// length = 0; -// err = sysctl(mib, 4, NULL, &length, NULL, 0); -// if (err == -1) { -// err = errno; -// } -// if (err == 0) { -// result = malloc(length); -// err = sysctl(mib, 4, result, &length, NULL, 0); -// if (err == -1) -// err = errno; -// if (err == ENOMEM) { -// free(result); /* clean up */ -// result = NULL; -// } -// } - -// p->pid = result->kp_proc.p_pid; -// p->ppid = result->kp_eproc.e_ppid; -// p->starttime = result->kp_proc.p_starttime.tv_sec; -// p->last_jiffies = result->kp_proc.p_cpticks; -// //p_pctcpu - -// return 0; -// } -- cgit v1.2.3