This source file includes following definitions.
- get_loadavg
- get_uptime
- get_meminfo
- get_task
- get_phys_addr
- get_long
- get_char
- get_array
- get_env
- get_arg
- get_stat
- array_read
1
2
3
4
5
6
7
8 #include <linux/types.h>
9 #include <linux/errno.h>
10 #include <linux/sched.h>
11 #include <linux/kernel.h>
12
13 #include <asm/segment.h>
14 #include <asm/io.h>
15
16 static int get_loadavg(char * buffer)
17 {
18 return sprintf(buffer,"%d.%02d %d.%02d %d.%02d\n",
19 avenrun[0] >> FSHIFT,
20 (FIXED_1/2 + (avenrun[0] & (FIXED_1-1))*100) >> FSHIFT,
21 avenrun[1] >> FSHIFT,
22 (FIXED_1/2 + (avenrun[1] & (FIXED_1-1))*100) >> FSHIFT,
23 avenrun[2] >> FSHIFT,
24 (FIXED_1/2 + (avenrun[2] & (FIXED_1-1))*100) >> FSHIFT);
25 }
26
27 static int get_uptime(char * buffer)
28 {
29 return sprintf(buffer,"%d\n",(jiffies+jiffies_offset)/HZ);
30 }
31
32 static int get_meminfo(char * buffer)
33 {
34 struct sysinfo i;
35
36 si_meminfo(&i);
37 si_swapinfo(&i);
38 return sprintf(buffer, " total: used: free: shared: buffers:\n"
39 "Mem: %8d %8d %8d %8d %8d\n"
40 "Swap: %8d %8d %8d\n",
41 i.totalram, i.totalram-i.freeram, i.freeram, i.sharedram, i.bufferram,
42 i.totalswap, i.totalswap-i.freeswap, i.freeswap);
43 }
44
45 static struct task_struct ** get_task(pid_t pid)
46 {
47 struct task_struct ** p;
48
49 p = task;
50 while (++p < task+NR_TASKS) {
51 if (*p && (*p)->pid == pid)
52 return p;
53 }
54 return NULL;
55 }
56
57 static unsigned long get_phys_addr(struct task_struct ** p, unsigned long ptr)
58 {
59 unsigned long page;
60
61 if (!p || !*p || ptr >= TASK_SIZE)
62 return 0;
63 page = (*p)->tss.cr3;
64 page += (ptr >> 20) & 0xffc;
65 page = *(unsigned long *) page;
66 if (!(page & 1))
67 return 0;
68 page &= 0xfffff000;
69 page += (ptr >> 10) & 0xffc;
70 page = *(unsigned long *) page;
71 if (!(page & 1))
72 return 0;
73 page &= 0xfffff000;
74 page += ptr & 0xfff;
75 return page;
76 }
77
78 static unsigned long get_long(struct task_struct ** p, unsigned long ptr)
79 {
80 unsigned long addr;
81
82 if (ptr & 3)
83 return 0;
84 addr = get_phys_addr(p,ptr);
85 if (!addr)
86 return 0;
87 return *(unsigned long *) addr;
88 }
89
90 static int get_char(struct task_struct ** p, unsigned long ptr)
91 {
92 unsigned long addr;
93
94 addr = get_phys_addr(p,ptr);
95 if (!addr)
96 return -1;
97 return *(unsigned char *) addr;
98 }
99
100 static int get_array(struct task_struct ** p, unsigned long ptr, char * buffer)
101 {
102 unsigned long tmp;
103 int size = 0, result = 0;
104 unsigned long array;
105 char c;
106
107 array = get_long(p,ptr);
108 if (!ptr)
109 return 0;
110 for (;;) {
111 tmp = get_long(p,array);
112 if (!tmp)
113 return result;
114 array += 4;
115 while ((c = get_char(p,tmp++)) > 0) {
116 if (size < PAGE_SIZE)
117 buffer[size++] = c;
118 else
119 return result;
120 }
121 if (c < 0)
122 return result;
123 result = size;
124 if (size < PAGE_SIZE)
125 buffer[size++] = '\0';
126 }
127 }
128
129 static int get_env(int pid, char * buffer)
130 {
131 struct task_struct ** p = get_task(pid);
132
133 if (!p || !*p)
134 return 0;
135 return get_array(p, (*p)->start_stack+8, buffer);
136 }
137
138 static int get_arg(int pid, char * buffer)
139 {
140 struct task_struct ** p = get_task(pid);
141
142 if (!p || !*p)
143 return 0;
144 return get_array(p, (*p)->start_stack+4, buffer);
145 }
146
147 static int get_stat(int pid, char * buffer)
148 {
149 struct task_struct ** p = get_task(pid);
150 char state;
151
152 if (!p || !*p)
153 return 0;
154 if ((*p)->state < 0)
155 state = '.';
156 else
157 state = "RSDZTD"[(*p)->state];
158 return sprintf(buffer,"%d (%s) %c %d %d %d %d\n",
159 pid,
160 (*p)->comm,
161 state,
162 (*p)->p_pptr->pid,
163 (*p)->pgrp,
164 (*p)->session,
165 (*p)->tty);
166 }
167
168 static int array_read(struct inode * inode, struct file * file,char * buf, int count)
169 {
170 char * page;
171 int length;
172 int end;
173 int type, pid;
174
175 if (count < 0)
176 return -EINVAL;
177 page = (char *) get_free_page(GFP_KERNEL);
178 *page = 0;
179 if (!page)
180 return -ENOMEM;
181 type = inode->i_ino;
182 pid = type >> 16;
183 type &= 0x0000ffff;
184 switch (type) {
185 case 2:
186 length = get_loadavg(page);
187 break;
188 case 3:
189 length = get_uptime(page);
190 break;
191 case 4:
192 length = get_meminfo(page);
193 break;
194 case 9:
195 length = get_env(pid, page);
196 break;
197 case 10:
198 length = get_arg(pid, page);
199 break;
200 case 11:
201 length = get_stat(pid, page);
202 break;
203 default:
204 return -EBADF;
205 }
206 if (file->f_pos >= length)
207 return 0;
208 if (count + file->f_pos > length)
209 count = length - file->f_pos;
210 end = count + file->f_pos;
211 memcpy_tofs(buf, page + file->f_pos, count);
212 free_page((unsigned long) page);
213 file->f_pos = end;
214 return count;
215 }
216
217 static struct file_operations proc_array_operations = {
218 NULL,
219 array_read,
220 NULL,
221 NULL,
222 NULL,
223 NULL,
224 NULL,
225 NULL,
226 NULL
227 };
228
229 struct inode_operations proc_array_inode_operations = {
230 &proc_array_operations,
231 NULL,
232 NULL,
233 NULL,
234 NULL,
235 NULL,
236 NULL,
237 NULL,
238 NULL,
239 NULL,
240 NULL,
241 NULL,
242 NULL,
243 NULL
244 };