use nprocs() function instead of /proc/cpuinfo
[lxde/lxtask.git] / src / xfce-taskmanager-linux.c
CommitLineData
580e78c2
HJYP
1/* $Id: xfce-taskmanager-linux.c 3940 2008-02-10 22:48:45Z nebulon $
2 *
3 * Copyright (c) 2006 Johannes Zellner, <webmaster@nebulon.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
a4a3fc0a 24#include <errno.h>
ac6cc864 25#include <unistd.h>
bdc67cb1 26#include <fcntl.h>
a4a3fc0a 27
580e78c2 28#include <glib/gi18n.h>
e3568c63 29#include <glib/gprintf.h>
580e78c2 30#include "xfce-taskmanager-linux.h"
ea07a859 31#include <sys/sysinfo.h>
ac6cc864 32
4ab5f812 33void get_task_details(pid_t pid,struct task *task)
0284f607 34{
bdc67cb1 35 int fd;
ac6cc864 36 gchar line[256];
4ab5f812
AG
37 gulong t_size, t_rss;
38 ssize_t ret;
0284f607 39
ac6cc864 40 task->pid=-1;
41 task->checked=FALSE;
2dbcf129 42 task->size=0;
ac6cc864 43
4ab5f812 44 sprintf(line,"/proc/%d/statm",(int)pid);
bdc67cb1 45 fd=open(line,O_RDONLY);
46 if(fd==-1) return;
4ab5f812
AG
47 ret = read(fd,line,255);
48 if (ret <= 0)
49 {
50 close(fd);
51 return;
52 }
53 line[ret] = '\0';
54 sscanf(line,"%lu %lu",&t_size,&t_rss);
2dbcf129 55 close(fd);
4ab5f812
AG
56 if(t_size == 0) return;
57 task->size = t_size * PAGE_SIZE;
58 task->rss = t_rss * PAGE_SIZE;
0284f607 59
4ab5f812 60 sprintf(line,"/proc/%d/stat",(gint)pid);
bdc67cb1 61 fd=open(line,O_RDONLY);
62 if(fd!=-1)
0284f607 63 {
ac6cc864 64 struct passwd *passwdp;
65 struct stat st;
05708dd1 66 char buf[2048],*p,*e;
ac6cc864 67 size_t len;
0284f607 68 gint utime = 0;
69 gint stime = 0;
4ab5f812 70 glong ppid;
0284f607 71
bdc67cb1 72 task->pid=pid;
73
5f1c09bf 74 ret=read(fd,buf,2048-1);
75 if(ret<=0)
76 {
77 close(fd);
78 return;
79 }
80 buf[ret]=0;
81 p=strchr(buf,'(');
82 if(p==NULL)
83 {
84 close(fd);
85 return;
86 }
87 p++;
05708dd1
AG
88 e = strrchr(p, ')');
89 if (e == NULL || e >= &p[sizeof(task->name)])
90 {
91 close(fd);
92 return;
93 }
94 len = e - p;
95 strncpy(task->name, p, len);
96 task->name[len]=0;
97 p = &e[1];
5ff47b84 98 if(show_full_path)
99 {
100 FILE *fp;
4ab5f812 101 sprintf(line,"/proc/%d/cmdline",(int)pid);
5ff47b84 102 fp=fopen(line,"r");
103 if(fp)
104 {
105 size_t size;
106 size=fread(task->name,1,sizeof(task->name)-1,fp);
107 if(size>0)
108 {
4ab5f812 109 size_t x;
5ff47b84 110 task->name[size]=0;
4ab5f812 111 for(x=0;x<size;x++)
5ff47b84 112 {
4ab5f812 113 if(task->name[x]=='\0')
5ff47b84 114 {
4ab5f812 115 if(task->name[x+1]=='\n')
5ff47b84 116 break;
4ab5f812 117 task->name[x]=' ';
5ff47b84 118 }
119 }
120 }
121 fclose(fp);
122 }
123 }
124 else if(len>=15)
626fdf69 125 {
126 FILE *fp;
4ab5f812 127 sprintf(line,"/proc/%d/cmdline",(int)pid);
626fdf69 128 fp=fopen(line,"r");
129 if(fp)
130 {
131 char *p;
4ab5f812
AG
132 if (fscanf(fp, "%255s", line) > 0)
133 {
134 p=strrchr(line,'/');
135 if(p != NULL)
136 strncpy(task->name, p+1, sizeof(task->name)-1);
137 else
138 strncpy(task->name, line, sizeof(task->name)-1);
139 task->name[sizeof(task->name)-1] = '\0';
140 }
626fdf69 141 fclose(fp);
626fdf69 142 }
143 }
bdc67cb1 144
4ab5f812 145 sscanf(p, "%1s %ld %s %s %s %s %s %s %s %s %s %i %i %s %s %s %i",
ac6cc864 146 task->state, // processstate
4ab5f812 147 &ppid, // parentid
0284f607 148 line, // processs groupid
149
150 line, // session id
151 line, // tty id
152 line, // tpgid: The process group ID of the process running on tty of the process
153 line, // flags
154 line, // minflt minor faults the process has maid
155
156 line, // cminflt
157 line, // majflt
158 line, // cmajflt
159 &utime, // utime the number of jiffies that this process has scheduled in user mode
160 &stime, // stime " kernel mode
161
162 line, // cutime " waited for children in user
163 line, // cstime " kernel mode
164 line, // priority (nice value + fifteen)
ac6cc864 165 &task->prio // nice range from 19 to -19 /* my change */
0284f607 166 );
ac6cc864 167 task->time = stime + utime;
168 task->old_time = task->time;
169 task->time_percentage = 0;
4ab5f812 170 task->ppid = ppid;
ac6cc864 171
bdc67cb1 172 fstat(fd,&st);
ac6cc864 173 task->uid=st.st_uid;
174 passwdp = getpwuid(task->uid);
175 if( passwdp != NULL && passwdp->pw_name != NULL)
176 g_strlcpy(task->uname, passwdp->pw_name, sizeof task->uname);
0284f607 177
bdc67cb1 178 close(fd);
0284f607 179 }
0284f607 180}
181
bdc67cb1 182static int proc_filter(const struct dirent *d)
183{
184 int c=d->d_name[0];
185 return c>='1' && c<='9';
186}
187
188GArray *get_task_list(void)
189{
190 GArray *task_list;
191 struct dirent **namelist;
192 int n;
193 int count=0;
194
195
196 task_list = g_array_new(FALSE, FALSE, sizeof (struct task));
197 n=scandir("/proc",&namelist,proc_filter,0);
198 if(n<0) return task_list;
199
200 g_array_set_size(task_list,n);
201 while(n--)
202 {
4ab5f812 203 pid_t pid = atol(namelist[n]->d_name);
bdc67cb1 204 struct task *task=&g_array_index(task_list, struct task, count);
a58111b0 205 free(namelist[n]);
bdc67cb1 206 get_task_details(pid,task);
4ab5f812 207 if(task->pid > 0 && task->size > 0) // don't show error or kenerl threads
bdc67cb1 208 {
209 count++;
210 }
211 }
212 task_list->len=count;
213 free(namelist);
214 return task_list;
215}
580e78c2
HJYP
216
217gboolean get_cpu_usage_from_proc(system_status *sys_stat)
218{
219 const gchar *file_name = "/proc/stat";
580e78c2
HJYP
220 FILE *file;
221
222 if ( sys_stat->valid_proc_reading == TRUE ) {
223 sys_stat->cpu_old_jiffies =
224 sys_stat->cpu_user +
225 sys_stat->cpu_nice +
226 sys_stat->cpu_system+
227 sys_stat->cpu_idle;
228 sys_stat->cpu_old_used =
229 sys_stat->cpu_user +
230 sys_stat->cpu_nice +
231 sys_stat->cpu_system;
232 } else {
233 sys_stat->cpu_old_jiffies = 0;
234 }
235
236 sys_stat->valid_proc_reading = FALSE;
237
bdc67cb1 238 file = fopen (file_name, "rb");
ac6cc864 239 if(!file) return FALSE;
240 if ( fscanf (file, "cpu\t%u %u %u %u",
241 &sys_stat->cpu_user,
242 &sys_stat->cpu_nice,
243 &sys_stat->cpu_system,
244 &sys_stat->cpu_idle
245 ) == 4 )
580e78c2 246 {
ac6cc864 247 sys_stat->valid_proc_reading = TRUE;
580e78c2 248 }
ac6cc864 249 fclose( file );
250 return TRUE;
580e78c2
HJYP
251}
252
253gboolean get_system_status (system_status *sys_stat)
254{
255 FILE *file;
ac6cc864 256 gchar buffer[100];
257 int reach;
258 static int cpu_count;
580e78c2 259
ac6cc864 260 file = fopen ("/proc/meminfo", "r");
261 if(!file) return FALSE;
262 reach=0;
263 while (fgets (buffer, 100, file) != NULL)
580e78c2 264 {
ac6cc864 265 if(!strncmp(buffer,"MemTotal:",9))
266 sys_stat->mem_total=atoi(buffer+10),reach++;
267 else if(!strncmp(buffer,"MemFree:",8))
268 sys_stat->mem_free=atoi(buffer+9),reach++;
269 else if(!strncmp(buffer,"Cached:",7))
270 sys_stat->mem_cached=atoi(buffer+8),reach++;
3022c6ce 271 else if(!strncmp(buffer,"Buffers:",8))
272 sys_stat->mem_buffered=atoi(buffer+9),reach++;
273 if(reach==4) break;
580e78c2 274 }
ac6cc864 275 fclose (file);
580e78c2 276
ac6cc864 277 if(!cpu_count)
580e78c2 278 {
ea07a859 279 cpu_count=get_nprocs();
580e78c2 280 }
ac6cc864 281 sys_stat->cpu_count=cpu_count;
580e78c2
HJYP
282 return TRUE;
283}
284
285void send_signal_to_task(gint task_id, gint signal)
286{
287 if(task_id > 0 && signal != 0)
288 {
289 gint ret = 0;
290
291 ret = kill(task_id, signal);
292
293 if(ret != 0)
a4a3fc0a 294 show_error(_("Couldn't send signal %d to the task with ID %d\n\n%s"), signal, task_id, g_strerror(errno) );
580e78c2
HJYP
295 }
296}
297
298
299void set_priority_to_task(gint task_id, gint prio)
300{
301 if(task_id > 0)
302 {
a4a3fc0a 303 int status = 0;
580e78c2
HJYP
304 gchar command[128] = "";
305 g_sprintf(command, "renice %d %d > /dev/null", prio, task_id);
306
a4a3fc0a 307 if( ! g_spawn_command_line_sync(command, NULL, NULL, &status, NULL) ||status )
580e78c2
HJYP
308 show_error(_("Couldn't set priority %d to the task with ID %d"), prio, task_id);
309 }
310}
311