Files
xfce4-taskmanager/src/functions.c
2005-11-09 21:13:14 +00:00

315 lines
8.0 KiB
C

/*
* xfce4-taskmanager - very simple taskmanger
*
* Copyright (c) 2005 Johannes Zellner, <webmaster@nebulon.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "functions.h"
gboolean refresh_task_list(void)
{
DIR *dir;
/* load the /proc dir */
if((dir = opendir(PROC_DIR_1)) == NULL)
{
if((dir = opendir(PROC_DIR_2)) == NULL)
{
if((dir = opendir(PROC_DIR_3)) == NULL)
{
fprintf(stderr, "Warning: couldn't load the /proc directory\n");
return FALSE;
}
}
}
struct dirent *dir_entry;
gint i;
/* markes all tasks to "not checked" */
for(i = 0; i < tasks; i++)
{
struct task *tmp = &g_array_index(task_array, struct task, i);
tmp->checked = FALSE;
}
while((dir_entry = readdir(dir)) != NULL)
{
if(atoi(dir_entry->d_name) != 0)
{
FILE *task_file_status;
gchar task_file_name_status[64] = "/proc/";
g_strlcat(task_file_name_status,dir_entry->d_name, sizeof task_file_name_status);
g_strlcat(task_file_name_status,"/status", sizeof task_file_name_status);
gchar buffer_status[256];
struct task task;
struct passwd *passwdp;
memset(&task, 0, sizeof(task));
if((task_file_status = fopen(task_file_name_status,"r")) != NULL)
{
while(fgets(buffer_status, sizeof buffer_status, task_file_status) != NULL)
{
#if defined(__NetBSD__)
/*
* NetBSD: /proc/number/status
* init 1 0 1 1 -1,-1 sldr 1131254603,930043 0,74940 0,87430 wait 0 0,0
*/
gchar dummy[255];
sscanf(buffer_status, "%s %i %i %s %s %s %s %s %s %s %s %i %s",
&task.name, &task.pid, &task.ppid, &dummy, &dummy, &dummy,
&dummy, &dummy, &dummy, &dummy, &dummy, &task.uid, &dummy);
#else
sscanf(buffer_status,"Uid: %i",&task.uid);
sscanf(buffer_status,"Pid: %i",&task.pid);
sscanf(buffer_status,"PPid: %i",&task.ppid);
sscanf(buffer_status,"Name: %s",&task.name);
sscanf(buffer_status,"VmSize: %i",&task.size);
sscanf(buffer_status,"VmRSS: %i",&task.rss);
// fix for freebsd with linux emo
sscanf(buffer_status,"VmRss: %i",&task.rss);
sscanf(buffer_status,"State: %c",&task.state);
#endif
}
passwdp = getpwuid(task.uid);
if(passwdp != NULL && passwdp->pw_name != NULL)
g_strlcpy(task.uname, passwdp->pw_name, sizeof task.uname);
}
fclose(task_file_status);
/* check if task is new and marks the task that its checked*/
gboolean new_task = TRUE;
for(i = 0; i < tasks; i++)
{
struct task *data = &g_array_index(task_array, struct task, i);
if((gint)data->pid == task.pid)
{
if((gint)data->ppid != task.ppid || (gchar)data->state != task.state || (unsigned int)data->size != task.size || (unsigned int)data->rss != task.rss)
{
data->ppid = task.ppid;
data->state = task.state;
data->size = task.size;
data->rss = task.rss;
refresh_list_item(i);
}
new_task = FALSE;
data->checked = TRUE;
break;
}
}
if(new_task)
{
task.checked = TRUE;
g_array_append_val(task_array, task);
tasks++;
if((show_user_tasks && task.uid == own_uid) || (show_root_tasks && task.uid == 0) || (show_other_tasks && task.uid != own_uid && task.uid != 0))
add_new_list_item(tasks-1);
}
}
}
closedir(dir);
/* removing all tasks, which are not "checked" */
for(i = 0; i < tasks; i++)
{
struct task *data = &g_array_index(task_array, struct task, i);
if(!data->checked)
{
remove_list_item((gint)data->pid);
task_array = g_array_remove_index(task_array, i);
tasks--;
}
}
printf("---------------------------------------------\n");
return TRUE;
}
void fill_list_item(gint i, GtkTreeIter *iter)
{
if(iter != NULL)
{
struct task *task = &g_array_index(task_array, struct task, i);
gchar *pid = g_strdup_printf("%i", task->pid);
gchar *ppid = g_strdup_printf("%i", task->ppid);
gchar *state = g_strdup_printf("%c", task->state);
gchar *size = g_strdup_printf("%i kb", task->size);
gchar *rss = g_strdup_printf("%i kb", task->rss);
gchar *name = g_strdup_printf("%s", task->name);
gchar *uname = g_strdup_printf("%s", task->uname);
gtk_list_store_set(GTK_LIST_STORE(list_store), iter, 0, name, -1);
gtk_list_store_set(GTK_LIST_STORE(list_store), iter, 1, pid, -1);
gtk_list_store_set(GTK_LIST_STORE(list_store), iter, 2, ppid, -1);
gtk_list_store_set(GTK_LIST_STORE(list_store), iter, 3, state, -1);
gtk_list_store_set(GTK_LIST_STORE(list_store), iter, 4, size, -1);
gtk_list_store_set(GTK_LIST_STORE(list_store), iter, 5, rss, -1);
gtk_list_store_set(GTK_LIST_STORE(list_store), iter, 6, uname, -1);
free(pid);
free(ppid);
free(state);
free(size);
free(rss);
free(name);
free(uname);
}
}
void add_new_list_item(gint i)
{
GtkTreeIter iter;
gtk_list_store_append(GTK_LIST_STORE(list_store), &iter);
fill_list_item(i, &iter);
}
void refresh_list_item(gint i)
{
GtkTreeIter iter;
gboolean valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list_store), &iter);
struct task task = g_array_index(task_array, struct task, i);
while(valid)
{
gchar *str_data = "";
gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, 1, &str_data, -1);
if(task.pid == atoi(str_data))
{
g_free(str_data);
fill_list_item(i, &iter);
break;
}
g_free(str_data);
valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(list_store), &iter);
}
}
void remove_list_item(gint pid)
{
GtkTreeIter iter;
gboolean valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list_store), &iter);
while(valid)
{
gchar *str_data = "";
gtk_tree_model_get(GTK_TREE_MODEL(list_store), &iter, 1, &str_data, -1);
if(pid == atoi(str_data))
{
free(str_data);
gtk_list_store_remove(GTK_LIST_STORE(list_store), &iter);
break;
}
free(str_data);
valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(list_store), &iter);
}
}
gint compare_list_item(GtkTreeModel *model, GtkTreeIter *iter1, GtkTreeIter *iter2, gpointer colnum)
{
gchar *s1 = "";
gchar *s2 = "";
gint ret = 0;
gtk_tree_model_get(model, iter1, colnum, &s1, -1);
gtk_tree_model_get(model, iter2, colnum, &s2, -1);
if((gint)colnum == 1 || (gint)colnum == 2 || (gint)colnum == 4 || (gint)colnum == 5)
{
gint i1 = 0;
gint i2 = 0;
if(s1 != NULL)
i1 = atoi(s1);
if(s2 != NULL)
i2 = atoi(s2);
if(i1 < i2)
ret = -1;
else
ret = 1;
}
else
{
if(s1 == NULL)
s1 = "";
if(s2 == NULL)
s2 = "";
ret = strcmp(s1, s2);
}
free(s1);
free(s2);
return ret;
}
/* function to send the signal to the current task */
void send_signal_to_task(gchar *task_id, gchar *signal)
{
if(task_id != "" && signal != NULL)
{
gchar command[64] = "kill -";
g_strlcat(command,signal, sizeof command);
g_strlcat(command," ", sizeof command);
g_strlcat(command,task_id, sizeof command);
if(system(command) != 0)
xfce_err("Couldn't %s the task with ID %s", signal, task_id);
}
}
/* change the task view (user, root, other) */
void change_task_view(void)
{
gtk_list_store_clear(GTK_LIST_STORE(list_store));
gint i = 0;
for(i = 0; i < tasks; i++)
{
struct task task = g_array_index(task_array, struct task, i);
if((task.uid == own_uid && show_user_tasks) || (task.uid == 0 && show_root_tasks) || (task.uid != own_uid && task.uid != 0 && show_other_tasks))
add_new_list_item(i);
}
refresh_task_list();
}