diff --git a/ChangeLog b/ChangeLog index 76c3a90..3874d18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2006-06-26 20:20 Johannes + + * rewrite of the taskmanager ;) + * now using seperate files for each os to get the processinfos + 2005-07-05 19:38 Johannes * added finnish translation diff --git a/NEWS b/NEWS index 3a04b5f..e69de29 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +0,0 @@ -20051109: ---------- - * inital NetBSD support....Thanks to Martti Kuparinen - -20050630: ---------- - * New version of xfce4-taskmanager (0.3.0). diff --git a/aclocal.m4 b/aclocal.m4 index 48426af..f54de75 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -7857,11 +7857,25 @@ AC_SUBST([am__untar]) dnl $Id$ dnl -dnl Copyright (c) 2002-2005 +dnl Copyright (c) 2002-2006 dnl The Xfce development team. All rights reserved. dnl dnl Written for Xfce by Benedikt Meurer . dnl +dnl This program is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the Free +dnl Software Foundation; either version 2 of the License, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +dnl more details. +dnl +dnl You should have received a copy of the GNU General Public License along with +dnl this program; if not, write to the Free Software Foundation, Inc., 59 Temple +dnl Place, Suite 330, Boston, MA 02111-1307 USA +dnl dnl xdt-depends dnl ----------- dnl Contains M4 macros to check for software dependencies. @@ -8273,11 +8287,25 @@ AC_DEFUN([BM_LIBXPM_REQUIRE], dnl $Id$ dnl -dnl Copyright (c) 2002-2005 +dnl Copyright (c) 2002-2006 dnl The Xfce development team. All rights reserved. dnl dnl Written for Xfce by Benedikt Meurer . dnl +dnl This program is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the Free +dnl Software Foundation; either version 2 of the License, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +dnl more details. +dnl +dnl You should have received a copy of the GNU General Public License along with +dnl this program; if not, write to the Free Software Foundation, Inc., 59 Temple +dnl Place, Suite 330, Boston, MA 02111-1307 USA +dnl dnl xdt-depends dnl ----------- dnl Contains M4 macros to check for software dependencies. @@ -8405,11 +8433,25 @@ AC_HELP_STRING([--enable-final], [Build final version]), dnl $Id$ dnl -dnl Copyright (c) 2002-2005 +dnl Copyright (c) 2002-2006 dnl The Xfce development team. All rights reserved. dnl dnl Written for Xfce by Benedikt Meurer . dnl +dnl This program is free software; you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the Free +dnl Software Foundation; either version 2 of the License, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but WITHOUT +dnl ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +dnl FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +dnl more details. +dnl +dnl You should have received a copy of the GNU General Public License along with +dnl this program; if not, write to the Free Software Foundation, Inc., 59 Temple +dnl Place, Suite 330, Boston, MA 02111-1307 USA +dnl dnl xdt-i18n dnl -------- dnl Internalization M4 macros. diff --git a/configure.ac b/configure.ac index 861d9df..3b10e7c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT([xfce4-taskmanager], [0.4.0-rc1], [xfce4-taskmanger@nebulon.de]) +AC_INIT([xfce4-taskmanager], [0.4.0-rc2], [xfce4-taskmanger@nebulon.de]) AM_CONFIG_HEADER([config.h]) AM_INIT_AUTOMAKE([AC_PACKAGE_TARNAME()], [AC_PACKAGE_VERSION()]) AM_MAINTAINER_MODE diff --git a/po/Makefile.in b/po/Makefile.in index 3f46cb3..27da035 100644 --- a/po/Makefile.in +++ b/po/Makefile.in @@ -14,7 +14,7 @@ GETTEXT_PACKAGE = xfce4-taskmanager PACKAGE = xfce4-taskmanager -VERSION = 0.4.0-rc1 +VERSION = 0.4.0-rc2 SHELL = /bin/sh @@ -32,7 +32,7 @@ localedir = $(libdir)/locale gnulocaledir = $(datadir)/locale gettextsrcdir = $(datadir)/glib-2.0/gettext/po subdir = po -install_sh = /home/the_hippie/Projekte/xfce4-taskmanager/trunk/install-sh +install_sh = /home/the_hippie/xfce4-taskmanager/trunk/install-sh mkdir_p = mkdir -p -- . mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs @@ -59,14 +59,14 @@ INCLUDES = -I.. -I$(top_srcdir)/intl COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) SOURCES = -POFILES = de.po eu.po fi.po fr.po hu.po pt_BR.po vi.po -GMOFILES = de.gmo eu.gmo fi.gmo fr.gmo hu.gmo pt_BR.gmo vi.gmo +POFILES = de.po eu.po fi.po fr.po hu.po ja.po pl.po pt_BR.po ru.po vi.po +GMOFILES = de.gmo eu.gmo fi.gmo fr.gmo hu.gmo ja.gmo pl.gmo pt_BR.gmo ru.gmo vi.gmo DISTFILES = ChangeLog Makefile.in.in POTFILES.in \ $(POFILES) $(GMOFILES) $(SOURCES) POTFILES = \ -CATALOGS = de.gmo eu.gmo fi.gmo fr.gmo hu.gmo pt_BR.gmo vi.gmo +CATALOGS = de.gmo eu.gmo fi.gmo fr.gmo hu.gmo ja.gmo pl.gmo pt_BR.gmo ru.gmo vi.gmo CATOBJEXT = .gmo INSTOBJEXT = .mo diff --git a/src/Makefile.am b/src/Makefile.am index aaa7dc3..89ca732 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,6 +9,7 @@ xfce4_taskmanager_SOURCES = \ callbacks.c callbacks.h \ functions.c functions.h \ interface.c interface.h \ + linux.c linux.h \ types.h xfce4_taskmanager_CFLAGS = \ diff --git a/src/functions.c b/src/functions.c index 5d0d903..d737647 100644 --- a/src/functions.c +++ b/src/functions.c @@ -22,185 +22,86 @@ gboolean refresh_task_list(void) { - DIR *dir; - struct dirent *dir_entry; - gint i; + gint i, j; + GArray *new_task_list; - /* load the /proc dir */ - if((dir = opendir(PROC_DIR_1)) == NULL) + /* gets the new task list */ + new_task_list = (GArray*) get_task_list(); + + /* markes all new_tasks to "not checked" */ + for(i = 0; i < new_task_list->len; i++) { - 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 task *new_tmp = &g_array_index(new_task_list, struct task, i); + new_tmp->checked = FALSE; } - - /* markes all tasks to "not checked" */ - for(i = 0; i < tasks; i++) + + /* check if task is new and marks the task that its checked*/ + for(i = 0; i < task_array->len; i++) { struct task *tmp = &g_array_index(task_array, struct task, i); tmp->checked = FALSE; + + for(j = 0; j < new_task_list->len; j++) + { + struct task *new_tmp = &g_array_index(new_task_list, struct task, j); + + if(new_tmp->pid == tmp->pid) + { + if((gint)tmp->ppid != (gint)new_tmp->ppid || strcmp(tmp->state,new_tmp->state) || (unsigned int)tmp->size != (unsigned int)new_tmp->size || (unsigned int)tmp->rss != (unsigned int)new_tmp->rss) + { + tmp->ppid = new_tmp->ppid; + strcpy(tmp->state, new_tmp->state); + tmp->size = new_tmp->size; + tmp->rss = new_tmp->rss; + + refresh_list_item(i); + } + tmp->checked = TRUE; + new_tmp->checked = TRUE; + break; + } + else + tmp->checked = FALSE; + } } - while((dir_entry = readdir(dir)) != NULL) + /* check for unchecked old-tasks for deleting */ + i = 0; + while( i < task_array->len) { - if(atoi(dir_entry->d_name) != 0) + + struct task *tmp = &g_array_index(task_array, struct task, i); + + if(tmp->checked == FALSE) { - FILE *task_file_status; - gchar buffer_status[256]; - struct task task; - struct passwd *passwdp; - struct stat status; - gchar task_file_name_status[64] = "/proc/"; - - g_strlcat(task_file_name_status,dir_entry->d_name, sizeof task_file_name_status); -#if defined(__NetBSD__) - g_strlcat(task_file_name_status,"/status", sizeof task_file_name_status); -#else - g_strlcat(task_file_name_status,"/stat", sizeof task_file_name_status); -#endif - - stat(task_file_name_status, &status); - - 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) - { - gchar dummy[255]; - -#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 - */ - - 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, &task.state, &task.uid, &dummy); - - task.size = -1; - task.rss = -1; -#else - //sscanf(buffer_status, "%d %s %c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d", - - sscanf(buffer_status, "%i %s %c %i %i %i %i %i %s %s %s %s %s %s %s %i %i %i %i %i %i %i %i %i %s %s %s %i %s %s %s %s %s %s %s %s %s %s %i %s %s", - &task.pid, // processid - &task.name, // processname - &task.state, // processstate - &task.ppid, // parentid - &dummy, // processs groupid - - &dummy, // session id - &dummy, // tty id - &dummy, // 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 - &dummy, // utime the number of jiffies that this process has scheduled in user mode - &dummy, // stime " kernel mode - - &dummy, // cutime " waited for children in user - &dummy, // cstime " kernel mode - &dummy, // priority (nice value + fifteen) - &dummy, // nice range from 19 to -19 - &dummy, // hardcoded 0 - - &dummy, // itrealvalue time in jiffies to next SIGALRM send to this process - &dummy, // starttime jiffies the process startet after system boot - &task.size, // vsize in bytes - &task.rss, // rss - &dummy, // rlim limit in bytes for rss - - &dummy, // startcode - &dummy, // endcode - &dummy, // 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 - &dummy, // CPU number last executed on - &dummy, - - &dummy - ); -#endif - } - - task.uid = status.st_uid; - passwdp = getpwuid(task.uid); - if(passwdp != NULL && passwdp->pw_name != NULL) - g_strlcpy(task.uname, passwdp->pw_name, sizeof task.uname); - } - - if(task_file_status != NULL) - 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 || strcmp(data->state,task.state) || (unsigned int)data->size != task.size || (unsigned int)data->rss != task.rss) - { - data->ppid = task.ppid; - strcpy(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); + remove_list_item((gint)tmp->pid); + g_array_remove_index(task_array, i); tasks--; } + else + i++; + } - + + + /* check for unchecked new tasks for inserting */ + for(i = 0; i < new_task_list->len; i++) + { + struct task *new_tmp = &g_array_index(new_task_list, struct task, i); + + if(!new_tmp->checked) + { + struct task new_task = *new_tmp; + + g_array_append_val(task_array, new_task); + if((show_user_tasks && new_task.uid == own_uid) || (show_root_tasks && new_task.uid == 0) || (show_other_tasks && new_task.uid != own_uid && new_task.uid != 0)) + add_new_list_item(tasks); + tasks++; + } + } + + g_array_free(new_task_list, TRUE); + return TRUE; } @@ -211,38 +112,38 @@ gboolean refresh_task_list(void) void load_config(void) { XfceRc *rc_file = xfce_rc_simple_open(config_file, FALSE); - + xfce_rc_set_group (rc_file, "General"); - + show_user_tasks = xfce_rc_read_bool_entry(rc_file, "show_user_tasks", TRUE); show_root_tasks = xfce_rc_read_bool_entry(rc_file, "show_root_tasks", FALSE); show_other_tasks = xfce_rc_read_bool_entry(rc_file, "show_other_tasks", FALSE); - + full_view = xfce_rc_read_bool_entry(rc_file, "full_view", FALSE); - + win_width = xfce_rc_read_int_entry(rc_file, "win_width", 500); win_height = xfce_rc_read_int_entry(rc_file, "win_height", 400); - + xfce_rc_close(rc_file); } void save_config(void) { XfceRc *rc_file = xfce_rc_simple_open(config_file, FALSE); - + xfce_rc_set_group (rc_file, "General"); - + xfce_rc_write_bool_entry(rc_file, "show_user_tasks", show_user_tasks); xfce_rc_write_bool_entry(rc_file, "show_root_tasks", show_root_tasks); xfce_rc_write_bool_entry(rc_file, "show_other_tasks", show_other_tasks); - + xfce_rc_write_bool_entry(rc_file, "full_view", full_view); gtk_window_get_size(GTK_WINDOW (main_window), &win_width, &win_height); - + xfce_rc_write_int_entry(rc_file, "win_width", win_width); xfce_rc_write_int_entry(rc_file, "win_height", win_height); - + xfce_rc_flush(rc_file); xfce_rc_close(rc_file); diff --git a/src/functions.h b/src/functions.h index c0a39e7..6c4726a 100644 --- a/src/functions.h +++ b/src/functions.h @@ -31,6 +31,7 @@ #include #include "types.h" +#include "linux.h" #define PROC_DIR_1 "/compat/linux/proc" #define PROC_DIR_2 "/emul/linux/proc" diff --git a/src/interface.c b/src/interface.c index cd871a0..4b69471 100644 --- a/src/interface.c +++ b/src/interface.c @@ -48,7 +48,7 @@ GtkWidget* create_main_window (void) scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolledwindow1); - gtk_scrolled_window_set_policy (scrolledwindow1, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start (GTK_BOX (vbox1), scrolledwindow1, TRUE, TRUE, 0); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_SHADOW_IN); diff --git a/src/interface.h b/src/interface.h index 1d38f7a..2a67d62 100644 --- a/src/interface.h +++ b/src/interface.h @@ -39,7 +39,8 @@ #include "functions.h" #include "callbacks.h" #include "types.h" - + +GtkListStore *list_store; GtkTreeSelection *selection; GtkWidget *treeview; GtkWidget *mainmenu; diff --git a/src/linux.c b/src/linux.c new file mode 100644 index 0000000..15778d2 --- /dev/null +++ b/src/linux.c @@ -0,0 +1,142 @@ +#include "linux.h" + +struct task get_task_details(gint pid) +{ + FILE *task_file; + FILE *cmdline_file; + gchar dummy[255]; + gchar buffer_status[256]; + struct task task; + struct passwd *passwdp; + struct stat status; + gchar filename[255]; + gchar cmdline_filename[255]; + + sprintf(filename, "/proc/%i/stat", pid); + sprintf(cmdline_filename, "/proc/%i/cmdline", pid); + + stat(filename, &status); + + memset(&task, 0, sizeof(task)); + + if((task_file = fopen(filename,"r")) != NULL) + { + while(fgets(buffer_status, sizeof buffer_status, task_file) != NULL) + { + sscanf(buffer_status, "%i (%255s %c %i %i %i %i %i %255s %255s %255s %255s %255s %255s %255s %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 + &dummy, // processs groupid + + &dummy, // session id + &dummy, // tty id + &dummy, // 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 + &dummy, // utime the number of jiffies that this process has scheduled in user mode + &dummy, // stime " kernel mode + + &dummy, // cutime " waited for children in user + &dummy, // cstime " kernel mode + &dummy, // priority (nice value + fifteen) + &dummy, // nice range from 19 to -19 + &dummy, // hardcoded 0 + + &dummy, // itrealvalue time in jiffies to next SIGALRM send to this process + &dummy, // starttime jiffies the process startet after system boot + &task.size, // vsize in bytes + &task.rss, // rss + &dummy, // rlim limit in bytes for rss + + &dummy, // startcode + &dummy, // endcode + &dummy, // 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 + &dummy, // CPU number last executed on + &dummy, + + &dummy + ); + } + + task.uid = status.st_uid; + passwdp = getpwuid(task.uid); + if(passwdp != NULL && passwdp->pw_name != NULL) + g_strlcpy(task.uname, passwdp->pw_name, sizeof task.uname); + } + + if(task_file != NULL) + fclose(task_file); + + if((cmdline_file = fopen(cmdline_filename,"r")) != NULL) + { + *dummy = NULL; + fscanf(cmdline_file, "%s", &dummy); + if(*dummy != NULL) + { + if(g_strrstr(dummy,"/") != NULL) + g_strlcpy(task.name, g_strrstr(dummy,"/")+1, 255); + else + g_strlcpy(task.name, dummy, 255); + + /* workaround for cmd-line entries with leading "-" */ + if(g_str_has_prefix(task.name, "-")) + sscanf(task.name, "-%255s", task.name); + } + } + + if(cmdline_file != NULL) + fclose(cmdline_file); + + if(g_str_has_suffix(task.name, ")")) + *g_strrstr(task.name, ")") = '\0'; + + return task; +} + +GArray *get_task_list() +{ + DIR *dir; + struct dirent *dir_entry; + GArray *task_list; + + task_list = g_array_new (FALSE, FALSE, sizeof (struct task)); + + if((dir = opendir("/proc/")) == NULL) + { + fprintf(stderr, "Error: couldn't load the /proc directory\n"); + return NULL; + } + + while((dir_entry = readdir(dir)) != NULL) + { + if(atoi(dir_entry->d_name) != 0) + { + struct task task = get_task_details(atoi(dir_entry->d_name)); + if(task.pid != -1) + g_array_append_val(task_list, task); + } + } + + closedir(dir); + + + return task_list; +} diff --git a/src/linux.h b/src/linux.h new file mode 100644 index 0000000..ee925bb --- /dev/null +++ b/src/linux.h @@ -0,0 +1,15 @@ +#ifndef LINUX_H +#define LINUX_H + +#include +#include +#include +#include +#include + +#include "types.h" + +struct task get_task_details(gint pid); +GArray *get_task_list(); + +#endif diff --git a/src/main.c b/src/main.c index db59a92..81c928e 100644 --- a/src/main.c +++ b/src/main.c @@ -34,6 +34,7 @@ int main (int argc, char *argv[]) { + #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); @@ -42,25 +43,25 @@ int main (int argc, char *argv[]) gtk_set_locale (); gtk_init (&argc, &argv); - + own_uid = getuid(); config_file = xfce_resource_save_location(XFCE_RESOURCE_CONFIG, "xfce4-taskmanager.rc", FALSE); load_config(); - + task_array = g_array_new (FALSE, FALSE, sizeof (struct task)); tasks = 0; main_window = create_main_window (); gtk_widget_show (main_window); - + if(!refresh_task_list()) return 0; g_timeout_add(REFRESH_INTERVAL, (gpointer) refresh_task_list, NULL); - + gtk_main (); - + return 0; } diff --git a/src/types.h b/src/types.h index 6c3dfe9..d463d2d 100644 --- a/src/types.h +++ b/src/types.h @@ -18,8 +18,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef __TYPES_H_ -#define __TYPES_H_ +#ifndef TYPES_H +#define TYPES_H + +#include #define REFRESH_INTERVAL 1000 @@ -37,7 +39,6 @@ struct task }; GtkWidget *main_window; -GtkListStore *list_store; GArray *task_array; gint tasks;