Show list of tasks

Provide the list of tasks through a GArray and parse it in main.c to
update the GtkTreeModel.
This commit is contained in:
Mike Massonnet
2010-05-05 08:53:49 +02:00
parent 71d1684696
commit a02bf69573
6 changed files with 443 additions and 112 deletions

View File

@@ -12,21 +12,137 @@
#include <config.h>
#endif
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "process-window.h"
#include "process-tree-view.h"
#include "task-manager.h"
static GtkWidget *window;
static XtmTaskManager *task_manager;
static gboolean timeout = 0;
static void
update_tree_iter (GtkTreeModel *model, GtkTreeIter *iter, Task *task)
{
gchar vsz[64], rss[64], cpu[16];
// TODO add precision for values < 1 MB
g_snprintf (vsz, 64, _("%lu MB"), task->vsz / 1024 / 1024);
g_snprintf (rss, 64, _("%lu MB"), task->rss / 1024 / 1024);
// TODO make precision optional
g_snprintf (cpu, 16, _("%.2f%%"), task->cpu_user + task->cpu_system);
gtk_list_store_set (GTK_LIST_STORE (model), iter,
XTM_PTV_COLUMN_PPID, task->ppid,
XTM_PTV_COLUMN_STATE, task->state,
XTM_PTV_COLUMN_VSZ, task->vsz,
XTM_PTV_COLUMN_VSZ_STR, vsz,
XTM_PTV_COLUMN_RSS, task->rss,
XTM_PTV_COLUMN_RSS_STR, rss,
XTM_PTV_COLUMN_CPU, task->cpu_user + task->cpu_system,
XTM_PTV_COLUMN_CPU_STR, cpu,
XTM_PTV_COLUMN_PRIORITY, task->prio,
-1);
}
static void
add_tree_iter (GtkTreeModel *model, Task *task)
{
GtkTreeIter iter;
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
XTM_PTV_COLUMN_COMMAND, task->cmdline,
XTM_PTV_COLUMN_PID, task->pid,
XTM_PTV_COLUMN_STATE, task->state,
XTM_PTV_COLUMN_UID, task->uid_name,
-1);
update_tree_iter (model, &iter, task);
}
static void
update_tree_model (const GArray *task_list)
{
GtkTreeModel *model;
GtkTreeIter iter;
Task *task;
guint i;
gboolean valid;
model = xtm_process_window_get_model (XTM_PROCESS_WINDOW (window));
// TODO pick a timestamp for started/terminated tasks to keep them momentary (red/green color, italic, ...)
/* Remove terminated tasks */
valid = gtk_tree_model_get_iter_first (model, &iter);
while (valid)
{
guint pid;
gboolean found = FALSE;
gtk_tree_model_get (model, &iter, XTM_PTV_COLUMN_PID, &pid, -1);
for (i = 0; i < task_list->len; i++)
{
task = &g_array_index (task_list, Task, i);
if (pid != task->pid)
continue;
found = TRUE;
break;
}
if (found == FALSE)
gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
valid = gtk_tree_model_iter_next (model, &iter);
}
/* Append started tasks and update existing ones */
for (i = 0; i < task_list->len; i++)
{
guint pid;
gboolean found = FALSE;
task = &g_array_index (task_list, Task, i);
valid = gtk_tree_model_get_iter_first (model, &iter);
while (valid)
{
gtk_tree_model_get (model, &iter, XTM_PTV_COLUMN_PID, &pid, -1);
if (pid == task->pid)
{
// TODO check if elements have to be updated, updating everything always is a CPU hog
update_tree_iter (model, &iter, task);
found = TRUE;
break;
}
valid = gtk_tree_model_iter_next (model, &iter);
}
if (found == FALSE)
{
add_tree_iter (model, task);
}
}
}
static gboolean
timeout_cb ()
init_timeout ()
{
guint num_processes;
gfloat cpu, memory, swap;
const GArray *task_list;
xtm_task_manager_get_system_info (task_manager, &num_processes, &cpu, &memory, &swap);
xtm_process_window_set_system_info (XTM_PROCESS_WINDOW (window), num_processes, cpu, memory, swap);
task_list = xtm_task_manager_get_task_list (task_manager);
update_tree_model (task_list);
if (timeout == 0)
timeout = g_timeout_add (1000, init_timeout, NULL);
return TRUE;
}
int main (int argc, char *argv[])
@@ -45,12 +161,14 @@ int main (int argc, char *argv[])
task_manager = xtm_task_manager_new ();
g_message ("Running as %s on %s", xtm_task_manager_get_username (task_manager), xtm_task_manager_get_hostname (task_manager));
g_timeout_add (1000, timeout_cb, NULL);
init_timeout ();
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_main ();
if (timeout > 0)
g_source_remove (timeout);
g_object_unref (window);
return 0;

View File

@@ -34,20 +34,6 @@ struct _XtmProcessTreeView
};
G_DEFINE_TYPE (XtmProcessTreeView, xtm_process_tree_view, GTK_TYPE_TREE_VIEW)
enum
{
COLUMN_COMMAND,
COLUMN_PID,
COLUMN_PPID,
COLUMN_STATE,
COLUMN_VSZ,
COLUMN_RSS,
COLUMN_UID,
COLUMN_CPU,
COLUMN_PRIORITY,
N_COLUMNS,
};
static gboolean treeview_clicked (XtmProcessTreeView *treeview, GdkEventButton *event);
static void settings_changed (GObject *object, GParamSpec *pspec, XtmProcessTreeView *treeview);
static int sort_by_string (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data);
@@ -74,10 +60,10 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview)
g_object_get (treeview->settings, "sort-column-id", &sort_column_id, "sort-type", &sort_type, NULL);
g_signal_connect (treeview->settings, "notify", G_CALLBACK (settings_changed), treeview);
treeview->model = gtk_list_store_new (9, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
treeview->model = gtk_list_store_new (XTM_PTV_N_COLUMNS, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_UINT64,
G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_FLOAT, G_TYPE_STRING, G_TYPE_INT);
g_object_set (treeview, "search-column", COLUMN_COMMAND, "model", treeview->model, NULL);
g_object_set (treeview, "search-column", XTM_PTV_COLUMN_COMMAND, "model", treeview->model, NULL);
cell_text = gtk_cell_renderer_text_new();
@@ -87,61 +73,60 @@ xtm_process_tree_view_init (XtmProcessTreeView *treeview)
cell_cmdline = gtk_cell_renderer_text_new ();
g_object_set (cell_cmdline, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
column = gtk_tree_view_column_new_with_attributes (_("Task"), cell_cmdline, "text", COLUMN_COMMAND, NULL);
column = gtk_tree_view_column_new_with_attributes (_("Task"), cell_cmdline, "text", XTM_PTV_COLUMN_COMMAND, NULL);
g_object_set (column, "expand", TRUE, "reorderable", FALSE, "resizable", TRUE, "visible", TRUE, NULL);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), COLUMN_COMMAND);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_COMMAND);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
g_object_get (treeview->settings, "column-pid", &visible, NULL);
column = gtk_tree_view_column_new_with_attributes (_("PID"), cell_right_aligned, "text", COLUMN_PID, NULL);
column = gtk_tree_view_column_new_with_attributes (_("PID"), cell_right_aligned, "text", XTM_PTV_COLUMN_PID, NULL);
g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), COLUMN_PID);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_PID);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
g_object_get (treeview->settings, "column-ppid", &visible, NULL);
column = gtk_tree_view_column_new_with_attributes (_("PPID"), cell_right_aligned, "text", COLUMN_PPID, NULL);
column = gtk_tree_view_column_new_with_attributes (_("PPID"), cell_right_aligned, "text", XTM_PTV_COLUMN_PPID, NULL);
g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), COLUMN_PPID);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_PPID);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
g_object_get (treeview->settings, "column-state", &visible, NULL);
column = gtk_tree_view_column_new_with_attributes (_("State"), cell_text, "text", COLUMN_STATE, NULL);
column = gtk_tree_view_column_new_with_attributes (_("State"), cell_text, "text", XTM_PTV_COLUMN_STATE, NULL);
g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), COLUMN_STATE);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_STATE);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
g_object_get (treeview->settings, "column-vsz", &visible, NULL);
column = gtk_tree_view_column_new_with_attributes (_("VSZ"), cell_right_aligned, "text", COLUMN_VSZ, NULL);
column = gtk_tree_view_column_new_with_attributes (_("VSZ"), cell_right_aligned, "text", XTM_PTV_COLUMN_VSZ_STR, NULL);
g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), COLUMN_VSZ);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_VSZ);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
g_object_get (treeview->settings, "column-rss", &visible, NULL);
column = gtk_tree_view_column_new_with_attributes (_("RSS"), cell_right_aligned, "text", COLUMN_RSS, NULL);
column = gtk_tree_view_column_new_with_attributes (_("RSS"), cell_right_aligned, "text", XTM_PTV_COLUMN_RSS_STR, NULL);
g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), COLUMN_RSS);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_RSS);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
g_object_get (treeview->settings, "column-uid", &visible, NULL);
column = gtk_tree_view_column_new_with_attributes (_("UID"), cell_text, "text", COLUMN_UID, NULL);
column = gtk_tree_view_column_new_with_attributes (_("UID"), cell_text, "text", XTM_PTV_COLUMN_UID, NULL);
g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), COLUMN_UID);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_UID);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
g_object_get (treeview->settings, "column-cpu", &visible, NULL);
column = gtk_tree_view_column_new_with_attributes (_("CPU"), cell_right_aligned, "text", COLUMN_CPU, NULL);
column = gtk_tree_view_column_new_with_attributes (_("CPU"), cell_right_aligned, "text", XTM_PTV_COLUMN_CPU_STR, NULL);
g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), COLUMN_CPU);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_CPU);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
g_object_get (treeview->settings, "column-priority", &visible, NULL);
/* TRANSLATORS: “Prio.” is short for Priority, it appears in the tree view header. */
column = gtk_tree_view_column_new_with_attributes (_("Prio."), cell_right_aligned, "text", COLUMN_PRIORITY, NULL);
column = gtk_tree_view_column_new_with_attributes (_("Prio."), cell_right_aligned, "text", XTM_PTV_COLUMN_PRIORITY, NULL);
g_object_set (column, "expand", FALSE, "reorderable", FALSE, "resizable", TRUE, "visible", visible, NULL);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), COLUMN_PRIORITY);
gtk_tree_view_column_set_sort_column_id (GTK_TREE_VIEW_COLUMN (column), XTM_PTV_COLUMN_PRIORITY);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (treeview->model), sort_by_string, NULL, NULL);
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (treeview->model), sort_column_id, sort_type);
g_signal_connect (treeview, "button-press-event", G_CALLBACK (treeview_clicked), NULL);
@@ -165,27 +150,27 @@ treeview_clicked (XtmProcessTreeView *treeview, GdkEventButton *event)
static void
settings_changed (GObject *object, GParamSpec *pspec, XtmProcessTreeView *treeview)
{
if (g_strstr_len (pspec->name, -1, "column-") != NULL)
if (g_str_has_prefix (pspec->name, "column-"))
{
gboolean visible;
gushort column_id;
if (!g_strcmp0 (pspec->name, "column-uid"))
column_id = COLUMN_UID;
column_id = XTM_PTV_COLUMN_UID;
else if (!g_strcmp0 (pspec->name, "column-pid"))
column_id = COLUMN_PID;
column_id = XTM_PTV_COLUMN_PID;
else if (!g_strcmp0 (pspec->name, "column-ppid"))
column_id = COLUMN_PPID;
column_id = XTM_PTV_COLUMN_PPID;
else if (!g_strcmp0 (pspec->name, "column-state"))
column_id = COLUMN_STATE;
column_id = XTM_PTV_COLUMN_STATE;
else if (!g_strcmp0 (pspec->name, "column-vsz"))
column_id = COLUMN_VSZ;
column_id = XTM_PTV_COLUMN_VSZ_STR;
else if (!g_strcmp0 (pspec->name, "column-rss"))
column_id = COLUMN_RSS;
column_id = XTM_PTV_COLUMN_RSS_STR;
else if (!g_strcmp0 (pspec->name, "column-cpu"))
column_id = COLUMN_CPU;
column_id = XTM_PTV_COLUMN_CPU_STR;
else if (!g_strcmp0 (pspec->name, "column-priority"))
column_id = COLUMN_PRIORITY;
column_id = XTM_PTV_COLUMN_PRIORITY;
g_object_get (object, pspec->name, &visible, NULL);
gtk_tree_view_column_set_visible (gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), column_id), visible);
@@ -198,46 +183,6 @@ settings_changed (GObject *object, GParamSpec *pspec, XtmProcessTreeView *treevi
}
}
static int
sort_by_string (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
{
gint sort_column_id;
GtkSortType order;
gchar *str1 = NULL, *str2 = NULL;
gchar *cstr1 = NULL, *cstr2 = NULL;
gint ret = 0;
g_debug (__func__);
if (!gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model), &sort_column_id, &order))
{
g_debug ("sort column default or unsorted: %d", sort_column_id);
return ret;
}
gtk_tree_model_get(model, a, sort_column_id, &str1, -1);
gtk_tree_model_get(model, b, sort_column_id, &str2, -1);
cstr1 = g_utf8_collate_key_for_filename (str1, -1);
cstr2 = g_utf8_collate_key_for_filename (str2, -1);
if (cstr1 != NULL && cstr2 != NULL)
{
ret = g_utf8_collate (cstr1, cstr2);
}
else if ((cstr1 == NULL && cstr2 != NULL) || (cstr1 != NULL && cstr2 == NULL))
{
ret = (cstr1 == NULL) ? -1 : 1;
}
g_free (str1);
g_free (str2);
g_free (cstr1);
g_free (cstr2);
return ret;
}
GtkWidget *

View File

@@ -16,6 +16,23 @@
#include <glib-object.h>
enum
{
XTM_PTV_COLUMN_COMMAND,
XTM_PTV_COLUMN_PID,
XTM_PTV_COLUMN_PPID,
XTM_PTV_COLUMN_STATE,
XTM_PTV_COLUMN_VSZ,
XTM_PTV_COLUMN_VSZ_STR,
XTM_PTV_COLUMN_RSS,
XTM_PTV_COLUMN_RSS_STR,
XTM_PTV_COLUMN_UID,
XTM_PTV_COLUMN_CPU,
XTM_PTV_COLUMN_CPU_STR,
XTM_PTV_COLUMN_PRIORITY,
XTM_PTV_N_COLUMNS,
};
#define XTM_TYPE_PROCESS_TREE_VIEW (xtm_process_tree_view_get_type ())
#define XTM_PROCESS_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XTM_TYPE_PROCESS_TREE_VIEW, XtmProcessTreeView))
#define XTM_PROCESS_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XTM_TYPE_PROCESS_TREE_VIEW, XtmProcessTreeViewClass))

View File

@@ -9,11 +9,18 @@
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <unistd.h>
#include <string.h>
#include <glib.h>
#include "task-manager.h"
static gushort _cpu_count = 0;
gboolean
get_memory_usage (guint64 *memory_total, guint64 *memory_free, guint64 *memory_cache, guint64 *memory_buffers, guint64 *swap_total, guint64 *swap_free)
{
@@ -23,9 +30,7 @@ get_memory_usage (guint64 *memory_total, guint64 *memory_free, guint64 *memory_c
gushort found = 0;
if ((file = fopen (filename, "r")) == NULL)
{
return FALSE;
}
while (found < 6 && fgets (buffer, 1024, file) != NULL)
{
@@ -58,21 +63,19 @@ get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system)
static gulong cur_jiffies_system = 0, old_jiffies_system = 0;
static gulong cur_jiffies = 0, old_jiffies = 0;
gulong user, user_nice, system, idle;
gushort count = 0;
if ((file = fopen (filename, "r")) == NULL)
{
return FALSE;
}
fgets (buffer, 1024, file);
sscanf (buffer, "cpu\t%u %u %u %u", &user, &user_nice, &system, &idle);
_cpu_count = 0;
while (fgets (buffer, 1024, file) != NULL)
{
if (buffer[0] != 'c' && buffer[1] != 'p' && buffer[2] != 'u')
break;
count += 1;
_cpu_count += 1;
}
fclose (file);
@@ -86,7 +89,175 @@ get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system)
*cpu_user = (old_jiffies > 0) ? (cur_jiffies_user - old_jiffies_user) * 100 / (gdouble)(cur_jiffies - old_jiffies) : 0;
*cpu_system = (old_jiffies > 0) ? (cur_jiffies_system - old_jiffies_system) * 100 / (gdouble)(cur_jiffies - old_jiffies) : 0;
*cpu_count = (count != 0) ? count : 1;
*cpu_count = (_cpu_count > 0) ? _cpu_count : 1;
_cpu_count = *cpu_count;
return TRUE;
}
static inline int get_pagesize ()
{
static int pagesize = 0;
if (pagesize == 0)
{
pagesize = sysconf (_SC_PAGESIZE);
if (pagesize == 0)
pagesize = 4096;
}
return pagesize;
}
static void
get_task_cmdline (Task *task)
{
FILE *file;
gchar filename[96];
gint i;
gchar c;
snprintf (filename, 96, "/proc/%i/cmdline", task->pid);
if ((file = fopen (filename, "r")) == NULL)
return;
/* Drop parentheses around task->name */
// FIXME comm concats the name to 15 chars
{
gchar *p;
g_strlcpy (task->name, &task->name[1], sizeof (task->name));
p = g_strrstr (task->name, ")");
*p = '\0';
}
/* Read byte per byte until EOF */
for (i = 0; (c = fgetc (file)) != EOF && i < sizeof (task->cmdline) - 1; i++)
task->cmdline[i] = (c == '\0') ? ' ' : c;
if (task->cmdline[i-1] == ' ')
task->cmdline[i-1] = '\0';
fclose (file);
/* Kernel processes don't have a cmdline nor an exec path */
if (i == 0)
{
size_t len = strlen (task->name);
g_strlcpy (&task->cmdline[1], task->name, len + 1);
task->cmdline[0] = '[';
task->cmdline[len+1] = ']';
task->cmdline[len+2] = '\0';
}
}
static gboolean
get_task_details (guint pid, Task *task)
{
FILE *file;
gchar filename[96];
gchar buffer[1024];
snprintf (filename, 96, "/proc/%d/stat", pid);
if ((file = fopen (filename, "r")) == NULL)
return FALSE;
fgets (buffer, 1024, file);
fclose (file);
{
gchar dummy[255];
gint idummy;
static gulong cur_j_user, cur_j_system;
static gulong old_j_user, old_j_system;
struct passwd *pw;
struct stat sstat;
sscanf(buffer, "%i %255s %1s %i %i %i %i %i %255s %255s %255s %255s %255s %i %i %i %i %i %i %i %i %i %i %i %255s %255s %255s %i %255s %255s %255s %255s %255s %255s %255s %255s %255s %255s %i %255s %255s",
&task->pid, // processid
task->name, // processname
task->state, // processstate
&task->ppid, // parentid
&idummy, // processs groupid
&idummy, // session id
&idummy, // tty id
&idummy, // tpgid the process group ID of the process running on tty of the process
dummy, // flags
dummy, // minflt minor faults the process has maid
dummy, // cminflt
dummy, // majflt
dummy, // cmajflt
&cur_j_user, // utime the number of jiffies that this process has scheduled in user mode
&cur_j_system, // stime " system mode
&idummy, // cutime " waited for children in user mode
&idummy, // cstime " system mode
&idummy, // priority (nice value + fifteen)
&task->prio, // nice range from 19 to -19
&idummy, // hardcoded 0
&idummy, // itrealvalue time in jiffies to next SIGALRM send to this process
&idummy, // starttime jiffies the process startet after system boot
&task->vsz, // vsize in bytes
&task->rss, // rss (number of pages in real memory)
dummy, // rlim limit in bytes for rss
dummy, // startcode
dummy, // endcode
&idummy, // startstack
dummy, // kstkesp value of esp (stack pointer)
dummy, // kstkeip value of EIP (instruction pointer)
dummy, // signal. bitmap of pending signals
dummy, // blocked: bitmap of blocked signals
dummy, // sigignore: bitmap of ignored signals
dummy, // sigcatch: bitmap of catched signals
dummy, // wchan
dummy, // nswap
dummy, // cnswap
dummy, // exit_signal
&idummy, // CPU number last executed on
dummy,
dummy
);
task->rss *= get_pagesize ();
task->cpu_user = (old_j_user > 0 && _cpu_count > 0) ? (cur_j_user - old_j_user) / (gfloat)_cpu_count : 0;
task->cpu_system = (old_j_system > 0 && _cpu_count > 0) ? (cur_j_system - old_j_system) / (gfloat)_cpu_count : 0;
stat (filename, &sstat);
pw = getpwuid (sstat.st_uid);
task->uid = sstat.st_uid;
g_strlcpy (task->uid_name, (pw != NULL) ? pw->pw_name : "nobody", sizeof (task->uid_name));
}
get_task_cmdline (task);
return TRUE;
}
gboolean
get_task_list (GArray *task_list)
{
GDir *dir;
const gchar *name;
guint pid;
Task task = { 0 };
if ((dir = g_dir_open ("/proc", 0, NULL)) == NULL)
return FALSE;
while ((name = g_dir_read_name(dir)) != NULL)
{
if ((pid = (guint)g_ascii_strtoull (name, NULL, 0)) > 0)
{
if (get_task_details (pid, &task))
{
g_array_append_val (task_list, task);
}
}
}
g_dir_close (dir);
return TRUE;
}

View File

@@ -66,6 +66,7 @@ xtm_task_manager_class_init (XtmTaskManagerClass *klass)
static void
xtm_task_manager_init (XtmTaskManager *manager)
{
manager->tasks = g_array_new (FALSE, FALSE, sizeof (Task));
get_owner_uid (&(manager->owner_uid), &(manager->owner_uid_name));
manager->hostname = get_hostname ();
}
@@ -74,6 +75,7 @@ static void
xtm_task_manager_finalize (GObject *object)
{
XtmTaskManager *manager = XTM_TASK_MANAGER (object);
g_array_free (manager->tasks, TRUE);
g_free (manager->owner_uid_name);
g_free (manager->hostname);
}
@@ -128,18 +130,13 @@ xtm_task_manager_get_hostname (XtmTaskManager *manager)
return manager->hostname;
}
GArray *
xtm_task_manager_get_tasklist (XtmTaskManager *manager)
{
}
void
xtm_task_manager_get_system_info (XtmTaskManager *manager, guint *num_processes, gfloat *cpu, gfloat *memory, gfloat *swap)
{
guint64 memory_used, swap_used;
/* Set number of processes */
*num_processes = 0;//manager->tasks->len;
*num_processes = manager->tasks->len;
/* Set memory and swap usage */
get_memory_usage (&manager->memory_total, &manager->memory_free, &manager->memory_cache, &manager->memory_buffers,
@@ -156,6 +153,87 @@ xtm_task_manager_get_system_info (XtmTaskManager *manager, guint *num_processes,
*cpu = manager->cpu_user + manager->cpu_system;
}
const GArray *
xtm_task_manager_get_task_list (XtmTaskManager *manager)
{
GArray *array;
guint i;
if (manager->tasks->len == 0)
{
get_task_list (manager->tasks);
#if 1|DEBUG
{
gint i;
for (i = 0; i < manager->tasks->len; i++)
{
Task *task = &g_array_index (manager->tasks, Task, i);
g_print ("%5d %5s %15s %.50s\n", task->pid, task->uid_name, task->name, task->cmdline);
}
}
#endif
return manager->tasks;
}
/* Retrieve new task list */
array = g_array_new (FALSE, FALSE, sizeof (Task));
get_task_list (array);
/* Remove terminated tasks */
for (i = 0; i < manager->tasks->len; i++)
{
guint j;
Task *task = &g_array_index (manager->tasks, Task, i);
gboolean found = FALSE;
for (j = 0; j < array->len; j++)
{
Task *tasktmp = &g_array_index (array, Task, j);
if (task->pid != tasktmp->pid)
continue;
found = TRUE;
break;
}
if (found == FALSE)
g_array_remove_index (manager->tasks, i);
}
/* Append started tasks and update existing ones */
for (i = 0; i < array->len; i++)
{
guint j;
Task *tasktmp = &g_array_index (array, Task, i);
gboolean found = FALSE;
for (j = 0; j < manager->tasks->len; j++)
{
Task *task = &g_array_index (manager->tasks, Task, j);
if (task->pid != tasktmp->pid)
continue;
found = TRUE;
task->ppid = tasktmp->ppid;
if (g_strcmp0 (task->state, tasktmp->state))
g_strlcpy (task->state, tasktmp->state, sizeof (task->state));
task->cpu_user = tasktmp->cpu_user;
task->cpu_system = tasktmp->cpu_system;
task->rss = tasktmp->rss;
task->vsz = tasktmp->vsz;
task->prio = tasktmp->prio;
break;
}
if (found == FALSE)
g_array_append_val (manager->tasks, tasktmp);
}
g_array_free (array, TRUE);
return manager->tasks;
}
void
xtm_task_manager_send_signal_to_pid (XtmTaskManager *manager)
{

View File

@@ -23,17 +23,18 @@
typedef struct _Task Task;
struct _Task
{
guint uid;
gchar uid_name[64];
guint pid;
guint ppid;
gchar program_name[64];
gchar full_cmdline[255];
gchar state[16];
gfloat cpu;
guint64 memory_vsz;
guint64 memory_rss;
gushort priority;
guint uid;
gchar uid_name[256];
guint pid;
guint ppid;
gchar name[256];
gchar cmdline[1024];
gchar state[16];
gfloat cpu_user;
gfloat cpu_system;
guint64 vsz;
guint64 rss;
gshort prio;
};
/**
@@ -42,7 +43,7 @@ struct _Task
gboolean get_memory_usage (guint64 *memory_total, guint64 *memory_free, guint64 *memory_cache, guint64 *memory_buffers, guint64 *swap_total, guint64 *swap_free);
gboolean get_cpu_usage (gushort *cpu_count, gfloat *cpu_user, gfloat *cpu_system);
//gboolean get_task_list (GArray *task_list);
gboolean get_task_list (GArray *task_list);
//void send_signal_to_task (gint task_id, gint signal);
//void set_priority_to_task (gint task_id, gint prio);
@@ -64,5 +65,6 @@ XtmTaskManager * xtm_task_manager_new ();
const gchar * xtm_task_manager_get_username (XtmTaskManager *manager);
const gchar * xtm_task_manager_get_hostname (XtmTaskManager *manager);
void xtm_task_manager_get_system_info (XtmTaskManager *manager, guint *num_processes, gfloat *cpu, gfloat *memory, gfloat *swap);
const GArray * xtm_task_manager_get_task_list (XtmTaskManager *manager);
#endif /* !TASK_MANAGER_H */