summaryrefslogtreecommitdiffstats
path: root/binding/task-manager-binding.c
diff options
context:
space:
mode:
Diffstat (limited to 'binding/task-manager-binding.c')
-rw-r--r--binding/task-manager-binding.c179
1 files changed, 179 insertions, 0 deletions
diff --git a/binding/task-manager-binding.c b/binding/task-manager-binding.c
new file mode 100644
index 0000000..43c9ee3
--- /dev/null
+++ b/binding/task-manager-binding.c
@@ -0,0 +1,179 @@
+#include <proc/readproc.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <proc/sysinfo.h>
+#include <math.h>
+#include <unistd.h>
+#include <json-c/json.h>
+
+#define AFB_BINDING_VERSION 2
+#include <afb/afb-binding.h>
+
+void get_process_list(struct afb_req request);
+struct pstat* fill_pstat(proc_t *proc_info);
+struct cpu_percentage* cpu_calculate(struct pstat*, struct pstat*);
+struct process_container* process_container_constr(char* process_name, int euid, struct pstat *pstat_values);
+static const struct afb_binding_interface *interface;
+static struct afb_event event;
+
+struct pstat {
+ long long unsigned int utime_ticks;
+ long long unsigned int cutime_ticks;
+ long long unsigned int stime_ticks;
+ long long unsigned int cstime_ticks;
+ long unsigned int cpu_total_time;
+};
+
+struct cpu_percentage {
+ double ucpu_usage;
+ double scpu_usage;
+};
+
+struct process_container {
+ char *process_name;
+ // int tid;
+ int euid;
+ struct pstat *pstat_values;
+};
+
+void get_process_list(struct afb_req request){
+
+ int seconds = 1, page_size;
+ page_size = getpagesize();
+ struct pstat *last_pstat_values, *now_pstat_values;
+ struct cpu_percentage *cpu_usage;
+ struct process_container *process_obj, *elem = NULL;
+ struct process_container* object_container[65535]; // array holding process objects
+ struct json_object *ret_json, *json_array, *json_obj;
+ ret_json = json_object_new_object();
+ json_array = json_object_new_array();
+ char state_str[2] = "\0";
+
+ PROCTAB* proc = openproc(PROC_FILLMEM | PROC_FILLSTAT);
+ if (!proc){
+ AFB_REQ_ERROR(request, "Unable to open /proc!");
+ afb_req_fail_f(request, "Failed", "Error processing arguments.");
+ }
+
+ proc_t* proc_info;
+ while ((proc_info = readproc(proc, NULL)) != NULL) {
+ last_pstat_values = fill_pstat(proc_info);
+ process_obj = process_container_constr(proc_info->cmd, proc_info->euid, last_pstat_values);
+ object_container[proc_info->tid] = process_obj;
+ freeproc(proc_info);
+ }
+
+ sleep(seconds);
+
+ proc = openproc(PROC_FILLMEM | PROC_FILLSTAT);
+ if (!proc){
+ AFB_REQ_ERROR(request, "Unable to open /proc!");
+ afb_req_fail_f(request, "Failed", "Error processing arguments.");
+ }
+
+ proc_t* proc_info2;
+ while ((proc_info2 = readproc(proc, NULL)) != NULL) {
+ now_pstat_values = fill_pstat(proc_info2);
+ elem = object_container[proc_info2->tid];
+ if(elem){
+ cpu_usage = cpu_calculate(elem->pstat_values, now_pstat_values);
+ json_obj = json_object_new_object();
+ json_object_object_add(json_obj, "cmd", json_object_new_string(proc_info2->cmd));
+ json_object_object_add(json_obj, "tid", json_object_new_int(proc_info2->tid));
+ json_object_object_add(json_obj, "euid", json_object_new_int(proc_info2->euid));
+ json_object_object_add(json_obj, "scpu", json_object_new_double(cpu_usage->scpu_usage));
+ json_object_object_add(json_obj, "ucpu", json_object_new_double(cpu_usage->ucpu_usage));
+ json_object_object_add(json_obj, "resident_mem", json_object_new_double((proc_info2->resident * page_size)/ pow(1024, 2)));
+ state_str[0] = proc_info2->state;
+ json_object_object_add(json_obj, "state", json_object_new_string(state_str));
+ json_object_array_add(json_array, json_obj);
+ }
+ freeproc(proc_info2);
+ }
+ json_object_object_add(ret_json, "processes", json_array);
+ afb_req_success(request, ret_json, NULL);
+
+ closeproc(proc);
+ // printf ("The json object created: %s\n", json_object_to_json_string(ret_json));
+}
+
+struct pstat* fill_pstat(proc_t *proc_info){
+
+ long unsigned int cpu_total_time;
+ long unsigned int cpu_time[10];
+ struct pstat *pstat_values = malloc(sizeof(struct pstat));
+
+ pstat_values->utime_ticks = proc_info->utime;
+ pstat_values->cutime_ticks = proc_info->cutime;
+ pstat_values->stime_ticks = proc_info->stime;
+ pstat_values->cstime_ticks = proc_info->cstime;
+
+ FILE *fstat = fopen("/proc/stat", "r");
+ if (fstat == NULL) {
+ perror("FOPEN ERROR ");
+ fclose(fstat);
+ }
+
+ memset(cpu_time, 0, sizeof(cpu_time));
+ if (fscanf(fstat, "%*s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
+ &cpu_time[0], &cpu_time[1], &cpu_time[2], &cpu_time[3],
+ &cpu_time[4], &cpu_time[5], &cpu_time[6], &cpu_time[7],
+ &cpu_time[8], &cpu_time[9]) == EOF) {
+ fclose(fstat);
+ }
+
+ fclose(fstat);
+
+ /*
+ * Returns total CPU time. It is a sum of user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice
+ */
+ for(int i = 0; i < 10; i++)
+ pstat_values->cpu_total_time += cpu_time[i];
+
+ return pstat_values;
+}
+
+struct cpu_percentage* cpu_calculate(struct pstat *last_pstat_values, struct pstat *now_pstat_values){
+
+ long unsigned int total_time_diff = now_pstat_values->cpu_total_time - last_pstat_values->cpu_total_time;
+
+ struct cpu_percentage *cpu_values = malloc(sizeof(struct cpu_percentage));
+
+ cpu_values->ucpu_usage = 100 * (((now_pstat_values->utime_ticks + now_pstat_values->cutime_ticks)
+ - (last_pstat_values->utime_ticks + last_pstat_values->cutime_ticks)) / (double) total_time_diff);
+
+ cpu_values->scpu_usage = 100 * (((now_pstat_values->stime_ticks + now_pstat_values->cstime_ticks)
+ - (last_pstat_values->stime_ticks + last_pstat_values->cstime_ticks)) / (double) total_time_diff);
+
+ return cpu_values;
+}
+
+struct process_container* process_container_constr(char* process_name, int euid, struct pstat *pstat_values) {
+
+ struct process_container *r = malloc(sizeof(struct process_container));
+ r->process_name = process_name;
+ r->euid = euid;
+ r->pstat_values = pstat_values;
+
+ return r;
+}
+
+static const struct afb_verb_v2 _afb_verbs_v2_taskmanager[] = {
+ {
+ .verb = "get_process_list",
+ .callback = get_process_list,
+ .auth = NULL,
+ .info = "Get an array of all processes currently running on the system",
+ .session = AFB_SESSION_NONE_V2
+ }
+};
+
+
+const struct afb_binding_v2 afbBindingV2 = {
+ .api = "taskmanager",
+ .specification = NULL,
+ .info = "Task Manager service",
+ .verbs = _afb_verbs_v2_taskmanager,
+ .noconcurrency = 0
+}; \ No newline at end of file