aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAngelo Marletta <angelo.marletta@gmail.com>2012-06-19 01:23:06 +0100
committerAngelo Marletta <angelo.marletta@gmail.com>2012-06-19 01:23:06 +0100
commit01a76753a060c27e26ac691c0d69f99b975038e5 (patch)
tree821fc1226395108504f2e850eff5d193956b7f95
parentfe3e3c7e3be29d29b3b7efc22f4933c64e883776 (diff)
downloadcpulimit-01a76753a060c27e26ac691c0d69f99b975038e5.tar.gz
process_iterator working for linux and freebsd. tests pass
-rw-r--r--src/Makefile10
-rw-r--r--src/process_iterator.c70
-rw-r--r--src/process_iterator.h2
-rw-r--r--tests/Makefile2
-rw-r--r--tests/process_iterator_test.c38
5 files changed, 98 insertions, 24 deletions
diff --git a/src/Makefile b/src/Makefile
index f7a71ed..7e2bc94 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -9,10 +9,10 @@ ifeq ($(UNAME), FreeBSD)
LIBS+=-lkvm
endif
-all:: $(TARGETS) process_iterator.o
+all:: process_iterator.o
-cpulimit: cpulimit.c $(LIBS)
- $(CC) -o cpulimit cpulimit.c $(LIBS) $(CFLAGS)
+#cpulimit: cpulimit.c $(LIBS)
+# $(CC) -o cpulimit cpulimit.c $(LIBS) $(CFLAGS)
process_iterator.o: process_iterator.c process_iterator.h
$(CC) -c process_iterator.c $(CFLAGS)
@@ -26,8 +26,8 @@ process_group.o: process_group.c process_group.h process_iterator.o list.o
#process.o: process.c process.h
# $(CC) -c process.c $(CFLAGS)
-procutils.o: procutils.c procutils.h
- $(CC) -c procutils.c $(CFLAGS)
+#procutils.o: procutils.c procutils.h
+# $(CC) -c procutils.c $(CFLAGS)
clean:
rm -f *~ *.o $(TARGETS)
diff --git a/src/process_iterator.c b/src/process_iterator.c
index eb34d62..ff13035 100644
--- a/src/process_iterator.c
+++ b/src/process_iterator.c
@@ -108,7 +108,7 @@ static int is_child_of(pid_t child_pid, pid_t parent_pid)
return ppid == parent_pid;
}
-int read_next_process(struct process_iterator *it, struct process *p)
+int get_next_process(struct process_iterator *it, struct process *p)
{
if (it->dip == NULL)
{
@@ -181,17 +181,67 @@ int init_process_iterator(struct process_iterator *it, struct process_filter *fi
return 0;
}
-int read_next_process(struct process_iterator *it, struct process *p) {
- if (it->i == it->count) return -1;
- p->pid = it->procs[it->i].ki_pid;
- p->ppid = it->procs[it->i].ki_ppid;
- p->cputime = it->procs[it->i].ki_runtime / 1000;
- p->starttime = it->procs[it->i].ki_start.tv_sec;
- it->i++;
- if (it->i == it->count) return -1;
+static void kproc2proc(struct kinfo_proc *kproc, struct process *proc)
+{
+ proc->pid = kproc->ki_pid;
+ proc->ppid = kproc->ki_ppid;
+ proc->cputime = kproc->ki_runtime / 1000;
+ proc->starttime = kproc->ki_start.tv_sec;
+}
+
+static int get_single_process(pid_t pid, struct process *process)
+{
+ kvm_t *kd;
+ int count;
+ char errbuf[_POSIX2_LINE_MAX];
+ /* Open the kvm interface, get a descriptor */
+ if ((kd = kvm_openfiles(NULL, _PATH_DEVNULL, NULL, O_RDONLY, errbuf)) == NULL) {
+ /* fprintf(stderr, "kvm_open: %s\n", errbuf); */
+ fprintf(stderr, "kvm_open: %s", errbuf);
+ return -1;
+ }
+ struct kinfo_proc *kproc = kvm_getprocs(kd, KERN_PROC_PID, pid, &count);
+ kvm_close(kd);
+ if (count == 0 || kproc == NULL)
+ {
+ fprintf(stderr, "kvm_getprocs: %s", kvm_geterr(kd));
+ return -1;
+ }
+ kproc2proc(kproc, process);
return 0;
}
+int get_next_process(struct process_iterator *it, struct process *p) {
+ if (it->i == it->count)
+ {
+ return -1;
+ }
+ if (it->filter->pid > 0 && !it->filter->include_children)
+ {
+ get_single_process(it->filter->pid, p);
+ it->i = it->count = 1;
+ return 0;
+ }
+ while (it->i < it->count)
+ {
+ if (it->filter->pid > 0 && it->filter->include_children)
+ {
+ kproc2proc(&(it->procs[it->i]), p);
+ it->i++;
+ if (p->pid != it->filter->pid && p->ppid != it->filter->pid)
+ continue;
+ return 0;
+ }
+ else if (it->filter->pid == 0)
+ {
+ kproc2proc(&(it->procs[it->i]), p);
+ it->i++;
+ return 0;
+ }
+ }
+ return -1;
+}
+
int close_process_iterator(struct process_iterator *it) {
return 0;
}
@@ -202,7 +252,7 @@ int init_process_iterator(struct process_iterator *it) {
return 0;
}
-int read_next_process(struct process_iterator *it, struct process *p) {
+int get_next_process(struct process_iterator *it, struct process *p) {
return -1;
}
diff --git a/src/process_iterator.h b/src/process_iterator.h
index 711cf3b..1e118f4 100644
--- a/src/process_iterator.h
+++ b/src/process_iterator.h
@@ -89,7 +89,7 @@ struct process_iterator {
int init_process_iterator(struct process_iterator *i, struct process_filter *filter);
-int read_next_process(struct process_iterator *i, struct process *p);
+int get_next_process(struct process_iterator *i, struct process *p);
int close_process_iterator(struct process_iterator *i);
diff --git a/tests/Makefile b/tests/Makefile
index 11359e6..d187359 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -14,7 +14,7 @@ all:: $(TARGETS)
busy: busy.c $(LIBS)
$(CC) -o busy busy.c $(LIBS) $(CFLAGS)
-process_iterator_test: process_iterator_test.c $(LIBS)
+process_iterator_test: process_iterator_test.c $(LIBS) ../src/process_iterator.o
$(CC) -I../src -o process_iterator_test process_iterator_test.c ../src/process_iterator.o $(LIBS) $(CFLAGS)
clean:
diff --git a/tests/process_iterator_test.c b/tests/process_iterator_test.c
index 1822449..ac5d542 100644
--- a/tests/process_iterator_test.c
+++ b/tests/process_iterator_test.c
@@ -18,24 +18,23 @@ int test_single_process()
count = 0;
now = time(NULL);
init_process_iterator(&it, &filter);
- while (read_next_process(&it, &process) == 0)
+ while (get_next_process(&it, &process) == 0)
{
assert(process.pid == getpid());
assert(process.ppid == getppid());
assert(process.cputime < 100);
assert(process.starttime == now || process.starttime == now - 1);
-
count++;
}
assert(count == 1);
close_process_iterator(&it);
//iterate children
filter.pid = getpid();
- filter.include_children = 1;
+ filter.include_children = 0;
count = 0;
now = time(NULL);
init_process_iterator(&it, &filter);
- while (read_next_process(&it, &process) == 0)
+ while (get_next_process(&it, &process) == 0)
{
assert(process.pid == getpid());
assert(process.ppid == getppid());
@@ -65,7 +64,7 @@ int test_multiple_process()
init_process_iterator(&it, &filter);
int count = 0;
time_t now = time(NULL);
- while (read_next_process(&it, &process) == 0)
+ while (get_next_process(&it, &process) == 0)
{
if (process.pid == getpid()) assert(process.ppid == getppid());
else if (process.pid == child) assert(process.ppid == getpid());
@@ -79,10 +78,35 @@ int test_multiple_process()
return 0;
}
+int test_all_processes()
+{
+ struct process_iterator it;
+ struct process process;
+ struct process_filter filter;
+ filter.pid = 0;
+ init_process_iterator(&it, &filter);
+ int count = 0;
+ time_t now = time(NULL);
+ while (get_next_process(&it, &process) == 0)
+ {
+ if (process.pid == getpid())
+ {
+ assert(process.ppid == getppid());
+ assert(process.cputime < 100);
+ assert(process.starttime == now || process.starttime == now - 1);
+ }
+ count++;
+ }
+ assert(count >= 10);
+ close_process_iterator(&it);
+ return 0;
+}
+
int main()
{
- printf("Current PID %d\n", getpid());
+ printf("Pid %d\n", getpid());
test_single_process();
test_multiple_process();
+ test_all_processes();
return 0;
-} \ No newline at end of file
+}
Un proyecto texto-plano.xyz