• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <ctype.h>
4 #include <fcntl.h>
5 
6 #include <string.h>
7 
8 #include <sys/stat.h>
9 #include <sys/types.h>
10 #include <dirent.h>
11 
12 #include <pwd.h>
13 
14 #include <cutils/sched_policy.h>
15 
nexttoksep(char ** strp,char * sep)16 static char *nexttoksep(char **strp, char *sep)
17 {
18     char *p = strsep(strp,sep);
19     return (p == 0) ? "" : p;
20 }
nexttok(char ** strp)21 static char *nexttok(char **strp)
22 {
23     return nexttoksep(strp, " ");
24 }
25 
26 #define SHOW_PRIO 1
27 #define SHOW_TIME 2
28 #define SHOW_POLICY 4
29 #define SHOW_CPU  8
30 #define SHOW_MACLABEL 16
31 #define SHOW_NUMERIC_UID 32
32 #define SHOW_ABI 64
33 
34 static int display_flags = 0;
35 
36 static void print_exe_abi(int pid);
37 
ps_line(int pid,int tid,char * namefilter)38 static int ps_line(int pid, int tid, char *namefilter)
39 {
40     char statline[1024];
41     char cmdline[1024];
42     char macline[1024];
43     char user[32];
44     struct stat stats;
45     int fd, r;
46     char *ptr, *name, *state;
47     int ppid;
48     unsigned wchan, rss, vss, eip;
49     unsigned utime, stime;
50     int prio, nice, rtprio, sched, psr;
51     struct passwd *pw;
52 
53     sprintf(statline, "/proc/%d", pid);
54     stat(statline, &stats);
55 
56     if(tid) {
57         sprintf(statline, "/proc/%d/task/%d/stat", pid, tid);
58         cmdline[0] = 0;
59         snprintf(macline, sizeof(macline), "/proc/%d/task/%d/attr/current", pid, tid);
60     } else {
61         sprintf(statline, "/proc/%d/stat", pid);
62         sprintf(cmdline, "/proc/%d/cmdline", pid);
63         snprintf(macline, sizeof(macline), "/proc/%d/attr/current", pid);
64         fd = open(cmdline, O_RDONLY);
65         if(fd == 0) {
66             r = 0;
67         } else {
68             r = read(fd, cmdline, 1023);
69             close(fd);
70             if(r < 0) r = 0;
71         }
72         cmdline[r] = 0;
73     }
74 
75     fd = open(statline, O_RDONLY);
76     if(fd == 0) return -1;
77     r = read(fd, statline, 1023);
78     close(fd);
79     if(r < 0) return -1;
80     statline[r] = 0;
81 
82     ptr = statline;
83     nexttok(&ptr); // skip pid
84     ptr++;          // skip "("
85 
86     name = ptr;
87     ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')',
88     *ptr++ = '\0';           // and null-terminate name.
89 
90     ptr++;          // skip " "
91     state = nexttok(&ptr);
92     ppid = atoi(nexttok(&ptr));
93     nexttok(&ptr); // pgrp
94     nexttok(&ptr); // sid
95     nexttok(&ptr); // tty
96     nexttok(&ptr); // tpgid
97     nexttok(&ptr); // flags
98     nexttok(&ptr); // minflt
99     nexttok(&ptr); // cminflt
100     nexttok(&ptr); // majflt
101     nexttok(&ptr); // cmajflt
102 #if 1
103     utime = atoi(nexttok(&ptr));
104     stime = atoi(nexttok(&ptr));
105 #else
106     nexttok(&ptr); // utime
107     nexttok(&ptr); // stime
108 #endif
109     nexttok(&ptr); // cutime
110     nexttok(&ptr); // cstime
111     prio = atoi(nexttok(&ptr));
112     nice = atoi(nexttok(&ptr));
113     nexttok(&ptr); // threads
114     nexttok(&ptr); // itrealvalue
115     nexttok(&ptr); // starttime
116     vss = strtoul(nexttok(&ptr), 0, 10); // vsize
117     rss = strtoul(nexttok(&ptr), 0, 10); // rss
118     nexttok(&ptr); // rlim
119     nexttok(&ptr); // startcode
120     nexttok(&ptr); // endcode
121     nexttok(&ptr); // startstack
122     nexttok(&ptr); // kstkesp
123     eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip
124     nexttok(&ptr); // signal
125     nexttok(&ptr); // blocked
126     nexttok(&ptr); // sigignore
127     nexttok(&ptr); // sigcatch
128     wchan = strtoul(nexttok(&ptr), 0, 10); // wchan
129     nexttok(&ptr); // nswap
130     nexttok(&ptr); // cnswap
131     nexttok(&ptr); // exit signal
132     psr = atoi(nexttok(&ptr)); // processor
133     rtprio = atoi(nexttok(&ptr)); // rt_priority
134     sched = atoi(nexttok(&ptr)); // scheduling policy
135 
136     nexttok(&ptr); // tty
137 
138     if(tid != 0) {
139         ppid = pid;
140         pid = tid;
141     }
142 
143     pw = getpwuid(stats.st_uid);
144     if(pw == 0 || (display_flags & SHOW_NUMERIC_UID)) {
145         sprintf(user,"%d",(int)stats.st_uid);
146     } else {
147         strcpy(user,pw->pw_name);
148     }
149 
150     if(!namefilter || !strncmp(name, namefilter, strlen(namefilter))) {
151         if (display_flags & SHOW_MACLABEL) {
152             fd = open(macline, O_RDONLY);
153             strcpy(macline, "-");
154             if (fd >= 0) {
155                 r = read(fd, macline, sizeof(macline)-1);
156                 close(fd);
157                 if (r > 0)
158                     macline[r] = 0;
159             }
160             printf("%-30s %-9s %-5d %-5d %s\n", macline, user, pid, ppid, cmdline[0] ? cmdline : name);
161             return 0;
162         }
163 
164         printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4);
165         if (display_flags & SHOW_CPU)
166             printf(" %-2d", psr);
167         if (display_flags & SHOW_PRIO)
168             printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched);
169         if (display_flags & SHOW_POLICY) {
170             SchedPolicy p;
171             if (get_sched_policy(pid, &p) < 0)
172                 printf(" un ");
173             else
174                 printf(" %.2s ", get_sched_policy_name(p));
175         }
176         printf(" %08x %08x %s ", wchan, eip, state);
177         if (display_flags & SHOW_ABI) {
178             print_exe_abi(pid);
179         }
180         printf("%s", cmdline[0] ? cmdline : name);
181         if(display_flags&SHOW_TIME)
182             printf(" (u:%d, s:%d)", utime, stime);
183 
184         printf("\n");
185     }
186     return 0;
187 }
188 
print_exe_abi(int pid)189 static void print_exe_abi(int pid)
190 {
191     int fd, r;
192     char exeline[1024];
193 
194     sprintf(exeline, "/proc/%d/exe", pid);
195     fd = open(exeline, O_RDONLY);
196     if(fd == 0) {
197         printf("    ");
198         return;
199     }
200     r = read(fd, exeline, 5 /* 4 byte ELFMAG + 1 byte EI_CLASS */);
201     close(fd);
202     if(r < 0) {
203         printf("    ");
204         return;
205     }
206     if (memcmp("\177ELF", exeline, 4) != 0) {
207         printf("??  ");
208         return;
209     }
210     switch (exeline[4]) {
211         case 1:
212             printf("32  ");
213             return;
214         case 2:
215             printf("64  ");
216             return;
217         default:
218             printf("??  ");
219             return;
220     }
221 }
222 
ps_threads(int pid,char * namefilter)223 void ps_threads(int pid, char *namefilter)
224 {
225     char tmp[128];
226     DIR *d;
227     struct dirent *de;
228 
229     sprintf(tmp,"/proc/%d/task",pid);
230     d = opendir(tmp);
231     if(d == 0) return;
232 
233     while((de = readdir(d)) != 0){
234         if(isdigit(de->d_name[0])){
235             int tid = atoi(de->d_name);
236             if(tid == pid) continue;
237             ps_line(pid, tid, namefilter);
238         }
239     }
240     closedir(d);
241 }
242 
ps_main(int argc,char ** argv)243 int ps_main(int argc, char **argv)
244 {
245     DIR *d;
246     struct dirent *de;
247     char *namefilter = 0;
248     int pidfilter = 0;
249     int threads = 0;
250 
251     d = opendir("/proc");
252     if(d == 0) return -1;
253 
254     while(argc > 1){
255         if(!strcmp(argv[1],"-t")) {
256             threads = 1;
257         } else if(!strcmp(argv[1],"-n")) {
258             display_flags |= SHOW_NUMERIC_UID;
259         } else if(!strcmp(argv[1],"-x")) {
260             display_flags |= SHOW_TIME;
261         } else if(!strcmp(argv[1], "-Z")) {
262             display_flags |= SHOW_MACLABEL;
263         } else if(!strcmp(argv[1],"-P")) {
264             display_flags |= SHOW_POLICY;
265         } else if(!strcmp(argv[1],"-p")) {
266             display_flags |= SHOW_PRIO;
267         } else if(!strcmp(argv[1],"-c")) {
268             display_flags |= SHOW_CPU;
269         } else if(!strcmp(argv[1],"--abi")) {
270             display_flags |= SHOW_ABI;
271         } else if(isdigit(argv[1][0])){
272             pidfilter = atoi(argv[1]);
273         } else {
274             namefilter = argv[1];
275         }
276         argc--;
277         argv++;
278     }
279 
280     if (display_flags & SHOW_MACLABEL) {
281         printf("LABEL                          USER     PID   PPID  NAME\n");
282     } else {
283         printf("USER     PID   PPID  VSIZE  RSS   %s%s %s WCHAN    PC        %sNAME\n",
284                (display_flags&SHOW_CPU)?"CPU ":"",
285                (display_flags&SHOW_PRIO)?"PRIO  NICE  RTPRI SCHED ":"",
286                (display_flags&SHOW_POLICY)?"PCY " : "",
287                (display_flags&SHOW_ABI)?"ABI " : "");
288     }
289     while((de = readdir(d)) != 0){
290         if(isdigit(de->d_name[0])){
291             int pid = atoi(de->d_name);
292             if(!pidfilter || (pidfilter == pid)) {
293                 ps_line(pid, 0, namefilter);
294                 if(threads) ps_threads(pid, namefilter);
295             }
296         }
297     }
298     closedir(d);
299     return 0;
300 }
301 
302