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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user