179 lines
4 KiB
C
179 lines
4 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "processes.h"
|
|
|
|
typedef unsigned int uint;
|
|
typedef unsigned long int ulong;
|
|
|
|
const ulong INIT_CAP = 1024;
|
|
|
|
struct process {
|
|
int pid;
|
|
int ppid;
|
|
char user[9];
|
|
int priority;
|
|
float cpu;
|
|
long resident_size;
|
|
long size;
|
|
long virtual_size;
|
|
char command[16];
|
|
};
|
|
|
|
struct processes {
|
|
ulong size;
|
|
ulong capacity;
|
|
struct process* procs;
|
|
};
|
|
|
|
struct query_result {
|
|
ulong size;
|
|
ulong i;
|
|
struct process** procs;
|
|
};
|
|
|
|
struct processes* new_processes() {
|
|
struct processes* p = malloc(sizeof(struct processes));
|
|
if (!p) {
|
|
return NULL;
|
|
}
|
|
|
|
struct process* p_arr = malloc(INIT_CAP * sizeof(struct process));
|
|
if (!p_arr) {
|
|
free(p);
|
|
return NULL;
|
|
}
|
|
|
|
p->size = 0;
|
|
p->capacity = INIT_CAP;
|
|
p->procs = p_arr;
|
|
return p;
|
|
}
|
|
|
|
void delete(struct processes* p) {
|
|
free(p->procs);
|
|
free(p);
|
|
}
|
|
|
|
int add_from_file(struct processes* ps, const char* filename) {
|
|
FILE* f = fopen(filename, "r");
|
|
if (!f) {
|
|
return 0;
|
|
}
|
|
|
|
struct process p;
|
|
while (fscanf(f, "%d %d %8s %d %f %ld %ld %ld %15s\n", &p.pid, &p.ppid,
|
|
p.user, &p.priority, &p.cpu, &p.resident_size, &p.size,
|
|
&p.virtual_size, p.command) == 9) {
|
|
// printf("%d %d %s %d %f %ld %ld %ld %s\n", p.pid, p.ppid,
|
|
// p.user, p.priority, p.cpu, p.resident_size, p.size,
|
|
// p.virtual_size, p.command);
|
|
if (ps->size == ps->capacity) {
|
|
ps->capacity *= 2;
|
|
struct process* new_procs = realloc(ps->procs,
|
|
ps->capacity * sizeof(struct process));
|
|
if (!new_procs) {
|
|
return 0;
|
|
}
|
|
ps->procs = new_procs;
|
|
}
|
|
|
|
ps->procs[ps->size] = p;
|
|
ps->size++;
|
|
}
|
|
|
|
fclose(f);
|
|
return 1;
|
|
}
|
|
|
|
void clear(struct processes* p) {
|
|
p->size = 0;
|
|
// may shrink p->procs here
|
|
}
|
|
|
|
struct query_result* search(struct processes* ps, const struct query* q) {
|
|
ulong capacity = INIT_CAP;
|
|
struct query_result* res = malloc(sizeof(struct query_result));
|
|
if (!res) {
|
|
return NULL;
|
|
}
|
|
|
|
res->size = 0;
|
|
res->i = 0;
|
|
res->procs = malloc(sizeof(struct process*) * capacity);
|
|
if (!res->procs) {
|
|
free(res);
|
|
return NULL;
|
|
}
|
|
|
|
for (ulong i = 0; i < ps->size; i++) {
|
|
int add;
|
|
|
|
struct process* p = &(ps->procs[i]);
|
|
|
|
add = (q->priority == 0 || (q->priority < 0 &&
|
|
(q->priority * -1) < p->priority) ||
|
|
(q->priority > 0 && q->priority == p->priority));
|
|
add = add && (q->rss == 0 || (q->rss < 0 &&
|
|
(q->rss * -1) < p->resident_size) ||
|
|
(q->rss > 0 && q->rss == p->resident_size));
|
|
add = add && (q->size == 0 || (q->size < 0 &&
|
|
(q->size * -1) < p->size) ||
|
|
(q->size > 0 && q->size == p->size));
|
|
add = add && (q->vsize == 0 || (q->vsize < 0 &&
|
|
(q->vsize * -1) < p->virtual_size) ||
|
|
(q->vsize > 0 && q->vsize == p->virtual_size));
|
|
add = add && (q->cpu_usage == 0 || (q->cpu_usage < 0 &&
|
|
q->cpu_usage * -1 < p->cpu) ||
|
|
(q->cpu_usage > 0 && q->cpu_usage == p->cpu));
|
|
|
|
|
|
if (add) {
|
|
res->procs[res->size] = p;
|
|
res->size++;
|
|
if (res->size == capacity) {
|
|
capacity *= 2;
|
|
struct process** new_procs = realloc(res->procs,
|
|
sizeof(struct process*) * capacity);
|
|
if (!new_procs) {
|
|
free(res->procs);
|
|
free(res);
|
|
return NULL;
|
|
}
|
|
res->procs = new_procs;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(res->size == 0) {
|
|
free(res->procs);
|
|
free(res);
|
|
return NULL;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
struct query_result* next(struct query_result* q) {
|
|
q->i++;
|
|
if (q->i == q->size) {
|
|
terminate_query(q);
|
|
return NULL;
|
|
}
|
|
return q;
|
|
}
|
|
|
|
void terminate_query(struct query_result* q) {
|
|
free(q->procs);
|
|
free(q);
|
|
}
|
|
|
|
int get_pid(struct query_result* r) { return r->procs[r->i]->pid; }
|
|
int get_ppid(struct query_result* r) { return r->procs[r->i]->ppid; }
|
|
const char* get_user (struct query_result* r) { return r->procs[r->i]->user; }
|
|
int get_priority(struct query_result* r) { return r->procs[r->i]->priority; }
|
|
float get_cpu_usage(struct query_result* r) { return r->procs[r->i]->cpu; }
|
|
long get_rss(struct query_result* r) { return r->procs[r->i]->resident_size; }
|
|
long get_size(struct query_result* r) { return r->procs[r->i]->size; }
|
|
long get_vsize(struct query_result* r) { return r->procs[r->i]->virtual_size; }
|
|
const char* get_command(struct query_result* r) { return r->procs[r->i]->command; }
|
|
|