[Xfce4-commits] <xfce4-taskmanager:master> Show list of tasks
Mike Massonnet
noreply at xfce.org
Wed May 5 09:08:08 CEST 2010
Updating branch refs/heads/master
to a02bf695731de0e02b21ff2a977afaf5ac67214c (commit)
from 71d1684696c49be2d73ebe98bd44177a33f8e9f8 (commit)
commit a02bf695731de0e02b21ff2a977afaf5ac67214c
Author: Mike Massonnet <mmassonnet at xfce.org>
Date: Wed May 5 08:53:49 2010 +0200
Show list of tasks
Provide the list of tasks through a GArray and parse it in main.c to
update the GtkTreeModel.
src/main.c | 122 ++++++++++++++++++++++++++++++-
src/process-tree-view.c | 115 ++++++++---------------------
src/process-tree-view.h | 17 ++++
src/task-manager-linux.c | 185 ++++++++++++++++++++++++++++++++++++++++++++--
src/task-manager.c | 90 +++++++++++++++++++++--
src/task-manager.h | 26 ++++---
6 files changed, 443 insertions(+), 112 deletions(-)
diff --git a/src/main.c b/src/main.c
index 5fac70f..2659c33 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;
diff --git a/src/process-tree-view.c b/src/process-tree-view.c
index e649f58..450681b 100644
--- a/src/process-tree-view.c
+++ b/src/process-tree-view.c
@@ -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 *
diff --git a/src/process-tree-view.h b/src/process-tree-view.h
index 71db963..481c552 100644
--- a/src/process-tree-view.h
+++ b/src/process-tree-view.h
@@ -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))
diff --git a/src/task-manager-linux.c b/src/task-manager-linux.c
index c207a11..d006bde 100644
--- a/src/task-manager-linux.c
+++ b/src/task-manager-linux.c
@@ -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;
}
diff --git a/src/task-manager.c b/src/task-manager.c
index ca5de7d..c12696a 100644
--- a/src/task-manager.c
+++ b/src/task-manager.c
@@ -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)
{
diff --git a/src/task-manager.h b/src/task-manager.h
index b1b05bd..76eb5eb 100644
--- a/src/task-manager.h
+++ b/src/task-manager.h
@@ -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 */
More information about the Xfce4-commits
mailing list