This source file includes following definitions.
- get_loadavg
- get_uptime
- get_meminfo
- get_version
- get_task
- get_phys_addr
- get_array
- get_env
- get_arg
- get_wchan
- get_stat
- get_statm
- array_read
1
2
3
4
5
6
7
8
9
10 #include <linux/types.h>
11 #include <linux/errno.h>
12 #include <linux/sched.h>
13 #include <linux/kernel.h>
14 #include <linux/tty.h>
15
16 #include <asm/segment.h>
17 #include <asm/io.h>
18
19 #define LOAD_INT(x) ((x) >> FSHIFT)
20 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
21
22 #ifdef CONFIG_DEBUG_MALLOC
23 int get_malloc(char * buffer);
24 #endif
25
26 static int get_loadavg(char * buffer)
27 {
28 int a, b, c;
29
30 a = avenrun[0] + (FIXED_1/200);
31 b = avenrun[1] + (FIXED_1/200);
32 c = avenrun[2] + (FIXED_1/200);
33 return sprintf(buffer,"%d.%02d %d.%02d %d.%02d\n",
34 LOAD_INT(a), LOAD_FRAC(a),
35 LOAD_INT(b), LOAD_FRAC(b),
36 LOAD_INT(c), LOAD_FRAC(c));
37 }
38
39 static int get_uptime(char * buffer)
40 {
41 unsigned long uptime;
42 unsigned long idle;
43
44 uptime = jiffies + jiffies_offset;
45 idle = task[0]->utime + task[0]->stime;
46 return sprintf(buffer,"%d.%02d %d.%02d\n",
47 uptime / HZ,
48 uptime % HZ,
49 idle / HZ,
50 idle % HZ);
51 }
52
53 static int get_meminfo(char * buffer)
54 {
55 struct sysinfo i;
56
57 si_meminfo(&i);
58 si_swapinfo(&i);
59 return sprintf(buffer, " total: used: free: shared: buffers:\n"
60 "Mem: %8d %8d %8d %8d %8d\n"
61 "Swap: %8d %8d %8d\n",
62 i.totalram, i.totalram-i.freeram, i.freeram, i.sharedram, i.bufferram,
63 i.totalswap, i.totalswap-i.freeswap, i.freeswap);
64 }
65
66 static int get_version(char * buffer)
67 {
68 extern char *linux_banner;
69
70 strcpy(buffer, linux_banner);
71 return strlen(buffer);
72 }
73
74 static struct task_struct ** get_task(pid_t pid)
75 {
76 struct task_struct ** p;
77
78 p = task;
79 while (++p < task+NR_TASKS) {
80 if (*p && (*p)->pid == pid)
81 return p;
82 }
83 return NULL;
84 }
85
86 static unsigned long get_phys_addr(struct task_struct ** p, unsigned long ptr)
87 {
88 unsigned long page;
89
90 if (!p || !*p || ptr >= TASK_SIZE)
91 return 0;
92 page = (*p)->tss.cr3;
93 page += (ptr >> 20) & 0xffc;
94 page = *(unsigned long *) page;
95 if (!(page & 1))
96 return 0;
97 page &= 0xfffff000;
98 page += (ptr >> 10) & 0xffc;
99 page = *(unsigned long *) page;
100 if (!(page & 1))
101 return 0;
102 page &= 0xfffff000;
103 page += ptr & 0xfff;
104 return page;
105 }
106
107 static int get_array(struct task_struct ** p, unsigned long start, unsigned long end, char * buffer)
108 {
109 unsigned long addr;
110 int size = 0, result = 0;
111 char c;
112
113 if (start >= end)
114 return result;
115 for (;;) {
116 addr = get_phys_addr(p, start);
117 if (!addr)
118 return result;
119 do {
120 c = *(char *) addr;
121 if (!c)
122 result = size;
123 if (size < PAGE_SIZE)
124 buffer[size++] = c;
125 else
126 return result;
127 addr++;
128 start++;
129 if (start >= end)
130 return result;
131 } while (!(addr & 0xfff));
132 }
133 }
134
135 static int get_env(int pid, char * buffer)
136 {
137 struct task_struct ** p = get_task(pid);
138
139 if (!p || !*p)
140 return 0;
141 return get_array(p, (*p)->env_start, (*p)->env_end, buffer);
142 }
143
144 static int get_arg(int pid, char * buffer)
145 {
146 struct task_struct ** p = get_task(pid);
147
148 if (!p || !*p)
149 return 0;
150 return get_array(p, (*p)->arg_start, (*p)->arg_end, buffer);
151 }
152
153 static unsigned long get_wchan(struct task_struct *p)
154 {
155 unsigned long ebp, eip;
156 unsigned long stack_page;
157 int count = 0;
158
159 if (!p || p == current || p->state == TASK_RUNNING)
160 return 0;
161 stack_page = p->kernel_stack_page;
162 if (!stack_page)
163 return 0;
164 ebp = p->tss.ebp;
165 do {
166 if (ebp < stack_page || ebp >= 4092+stack_page)
167 return 0;
168 eip = *(unsigned long *) (ebp+4);
169 if ((void *)eip != sleep_on &&
170 (void *)eip != interruptible_sleep_on)
171 return eip;
172 ebp = *(unsigned long *) ebp;
173 } while (count++ < 16);
174 return 0;
175 }
176
177 #define KSTK_EIP(stack) (((unsigned long *)stack)[1019])
178 #define KSTK_ESP(stack) (((unsigned long *)stack)[1022])
179
180 static int get_stat(int pid, char * buffer)
181 {
182 struct task_struct ** p = get_task(pid);
183 unsigned long sigignore=0, sigcatch=0, bit=1, wchan;
184 unsigned long vsize, eip, esp;
185 int i,tty_pgrp;
186 char state;
187
188 if (!p || !*p)
189 return 0;
190 if ((*p)->state < 0 || (*p)->state > 5)
191 state = '.';
192 else
193 state = "RSDZTD"[(*p)->state];
194 eip = esp = 0;
195 vsize = (*p)->kernel_stack_page;
196 if (vsize) {
197 eip = KSTK_EIP(vsize);
198 esp = KSTK_ESP(vsize);
199 vsize = (*p)->brk + 4095;
200 if (esp)
201 vsize += TASK_SIZE - esp;
202 }
203 wchan = get_wchan(*p);
204 for(i=0; i<32; ++i) {
205 switch((int) (*p)->sigaction[i].sa_handler) {
206 case 1: sigignore |= bit; break;
207 case 0: break;
208 default: sigcatch |= bit;
209 } bit <<= 1;
210 }
211 tty_pgrp = (*p)->tty;
212 if (tty_pgrp > 0 && tty_table[tty_pgrp])
213 tty_pgrp = tty_table[tty_pgrp]->pgrp;
214 else
215 tty_pgrp = -1;
216 return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %u %u \
217 %u %u %u %d %d %d %d %d %d %u %u %d %u %u %u %u %u %u %u %u %d \
218 %d %d %d %u\n",
219 pid,
220 (*p)->comm,
221 state,
222 (*p)->p_pptr->pid,
223 (*p)->pgrp,
224 (*p)->session,
225 (*p)->tty,
226 tty_pgrp,
227 (*p)->flags,
228 (*p)->min_flt,
229 (*p)->cmin_flt,
230 (*p)->maj_flt,
231 (*p)->cmaj_flt,
232 (*p)->utime,
233 (*p)->stime,
234 (*p)->cutime,
235 (*p)->cstime,
236 (*p)->counter,
237
238 (*p)->priority,
239
240 (*p)->timeout,
241 (*p)->it_real_value,
242 (*p)->start_time,
243 vsize,
244 (*p)->rss,
245 (*p)->rlim[RLIMIT_RSS].rlim_cur,
246 (*p)->start_code,
247 (*p)->end_code,
248 (*p)->start_stack,
249 esp,
250 eip,
251 (*p)->signal,
252 (*p)->blocked,
253 sigignore,
254 sigcatch,
255 wchan);
256 }
257
258 static int get_statm(int pid, char * buffer)
259 {
260 struct task_struct ** p = get_task(pid);
261 int i, tpag;
262 int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0;
263 unsigned long ptbl, *buf, *pte, *pagedir, map_nr;
264
265 if (!p || !*p)
266 return 0;
267 tpag = (*p)->end_code / PAGE_SIZE;
268 if ((*p)->state != TASK_ZOMBIE) {
269 pagedir = (unsigned long *)((*p)->tss.cr3 + ((*p)->start_code >> 20));
270 for (i = 0; i < 0x300; ++i) {
271 if ((ptbl = pagedir[i]) == 0) {
272 tpag -= 1024;
273 continue;
274 }
275 buf = (unsigned long *)(ptbl & 0xfffff000);
276 for (pte = buf; pte < (buf + 1024); ++pte) {
277 if (*pte != 0) {
278 ++size;
279 if (*pte & 1) {
280 ++resident;
281 if (tpag > 0)
282 ++trs;
283 else
284 ++drs;
285 if (i >= 15 && i < 0x2f0) {
286 ++lrs;
287 if (*pte & 0x40)
288 ++dt;
289 else
290 --drs;
291 }
292 map_nr = MAP_NR(*pte);
293 if (map_nr < (high_memory / 4096) && mem_map[map_nr] > 1)
294 ++share;
295 }
296 }
297 --tpag;
298 }
299 }
300 }
301 return sprintf(buffer,"%d %d %d %d %d %d %d\n",
302 size, resident, share, trs, lrs, drs, dt);
303 }
304
305 static int array_read(struct inode * inode, struct file * file,char * buf, int count)
306 {
307 char * page;
308 int length;
309 int end;
310 unsigned int type, pid;
311
312 if (count < 0)
313 return -EINVAL;
314 page = (char *) get_free_page(GFP_KERNEL);
315 if (!page)
316 return -ENOMEM;
317 type = inode->i_ino;
318 pid = type >> 16;
319 type &= 0x0000ffff;
320 switch (type) {
321 case 2:
322 length = get_loadavg(page);
323 break;
324 case 3:
325 length = get_uptime(page);
326 break;
327 case 4:
328 length = get_meminfo(page);
329 break;
330 case 6:
331 length = get_version(page);
332 break;
333 case 9:
334 length = get_env(pid, page);
335 break;
336 case 10:
337 length = get_arg(pid, page);
338 break;
339 case 11:
340 length = get_stat(pid, page);
341 break;
342 case 12:
343 length = get_statm(pid, page);
344 break;
345 #ifdef CONFIG_DEBUG_MALLOC
346 case 13:
347 length = get_malloc(page);
348 break;
349 #endif
350 default:
351 free_page((unsigned long) page);
352 return -EBADF;
353 }
354 if (file->f_pos >= length) {
355 free_page((unsigned long) page);
356 return 0;
357 }
358 if (count + file->f_pos > length)
359 count = length - file->f_pos;
360 end = count + file->f_pos;
361 memcpy_tofs(buf, page + file->f_pos, count);
362 free_page((unsigned long) page);
363 file->f_pos = end;
364 return count;
365 }
366
367 static struct file_operations proc_array_operations = {
368 NULL,
369 array_read,
370 NULL,
371 NULL,
372 NULL,
373 NULL,
374 NULL,
375 NULL,
376 NULL,
377 NULL
378 };
379
380 struct inode_operations proc_array_inode_operations = {
381 &proc_array_operations,
382 NULL,
383 NULL,
384 NULL,
385 NULL,
386 NULL,
387 NULL,
388 NULL,
389 NULL,
390 NULL,
391 NULL,
392 NULL,
393 NULL,
394 NULL,
395 NULL
396 };