• 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 
32 static int display_flags = 0;
33 
ps_line(int pid,int tid,char * namefilter)34 static int ps_line(int pid, int tid, char *namefilter)
35 {
36     char statline[1024];
37     char cmdline[1024];
38     char macline[1024];
39     char user[32];
40     struct stat stats;
41     int fd, r;
42     char *ptr, *name, *state;
43     int ppid, tty;
44     unsigned wchan, rss, vss, eip;
45     unsigned utime, stime;
46     int prio, nice, rtprio, sched, psr;
47     struct passwd *pw;
48 
49     sprintf(statline, "/proc/%d", pid);
50     stat(statline, &stats);
51 
52     if(tid) {
53         sprintf(statline, "/proc/%d/task/%d/stat", pid, tid);
54         cmdline[0] = 0;
55         snprintf(macline, sizeof(macline), "/proc/%d/task/%d/attr/current", pid, tid);
56     } else {
57         sprintf(statline, "/proc/%d/stat", pid);
58         sprintf(cmdline, "/proc/%d/cmdline", pid);
59         snprintf(macline, sizeof(macline), "/proc/%d/attr/current", pid);
60         fd = open(cmdline, O_RDONLY);
61         if(fd == 0) {
62             r = 0;
63         } else {
64             r = read(fd, cmdline, 1023);
65             close(fd);
66             if(r < 0) r = 0;
67         }
68         cmdline[r] = 0;
69     }
70 
71     fd = open(statline, O_RDONLY);
72     if(fd == 0) return -1;
73     r = read(fd, statline, 1023);
74     close(fd);
75     if(r < 0) return -1;
76     statline[r] = 0;
77 
78     ptr = statline;
79     nexttok(&ptr); // skip pid
80     ptr++;          // skip "("
81 
82     name = ptr;
83     ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')',
84     *ptr++ = '\0';           // and null-terminate name.
85 
86     ptr++;          // skip " "
87     state = nexttok(&ptr);
88     ppid = atoi(nexttok(&ptr));
89     nexttok(&ptr); // pgrp
90     nexttok(&ptr); // sid
91     tty = atoi(nexttok(&ptr));
92 
93     nexttok(&ptr); // tpgid
94     nexttok(&ptr); // flags
95     nexttok(&ptr); // minflt
96     nexttok(&ptr); // cminflt
97     nexttok(&ptr); // majflt
98     nexttok(&ptr); // cmajflt
99 #if 1
100     utime = atoi(nexttok(&ptr));
101     stime = atoi(nexttok(&ptr));
102 #else
103     nexttok(&ptr); // utime
104     nexttok(&ptr); // stime
105 #endif
106     nexttok(&ptr); // cutime
107     nexttok(&ptr); // cstime
108     prio = atoi(nexttok(&ptr));
109     nice = atoi(nexttok(&ptr));
110     nexttok(&ptr); // threads
111     nexttok(&ptr); // itrealvalue
112     nexttok(&ptr); // starttime
113     vss = strtoul(nexttok(&ptr), 0, 10); // vsize
114     rss = strtoul(nexttok(&ptr), 0, 10); // rss
115     nexttok(&ptr); // rlim
116     nexttok(&ptr); // startcode
117     nexttok(&ptr); // endcode
118     nexttok(&ptr); // startstack
119     nexttok(&ptr); // kstkesp
120     eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip
121     nexttok(&ptr); // signal
122     nexttok(&ptr); // blocked
123     nexttok(&ptr); // sigignore
124     nexttok(&ptr); // sigcatch
125     wchan = strtoul(nexttok(&ptr), 0, 10); // wchan
126     nexttok(&ptr); // nswap
127     nexttok(&ptr); // cnswap
128     nexttok(&ptr); // exit signal
129     psr = atoi(nexttok(&ptr)); // processor
130     rtprio = atoi(nexttok(&ptr)); // rt_priority
131     sched = atoi(nexttok(&ptr)); // scheduling policy
132 
133     tty = atoi(nexttok(&ptr));
134 
135     if(tid != 0) {
136         ppid = pid;
137         pid = tid;
138     }
139 
140     pw = getpwuid(stats.st_uid);
141     if(pw == 0) {
142         sprintf(user,"%d",(int)stats.st_uid);
143     } else {
144         strcpy(user,pw->pw_name);
145     }
146 
147     if(!namefilter || !strncmp(name, namefilter, strlen(namefilter))) {
148         if (display_flags & SHOW_MACLABEL) {
149             fd = open(macline, O_RDONLY);
150             strcpy(macline, "-");
151             if (fd >= 0) {
152                 r = read(fd, macline, sizeof(macline)-1);
153                 close(fd);
154                 if (r > 0)
155                     macline[r] = 0;
156             }
157             printf("%-30s %-9s %-5d %-5d %s\n", macline, user, pid, ppid, cmdline[0] ? cmdline : name);
158             return 0;
159         }
160 
161         printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4);
162         if (display_flags & SHOW_CPU)
163             printf(" %-2d", psr);
164         if (display_flags & SHOW_PRIO)
165             printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched);
166         if (display_flags & SHOW_POLICY) {
167             SchedPolicy p;
168             if (get_sched_policy(pid, &p) < 0)
169                 printf(" un ");
170             else
171                 printf(" %.2s ", get_sched_policy_name(p));
172         }
173         printf(" %08x %08x %s %s", wchan, eip, state, cmdline[0] ? cmdline : name);
174         if(display_flags&SHOW_TIME)
175             printf(" (u:%d, s:%d)", utime, stime);
176 
177         printf("\n");
178     }
179     return 0;
180 }
181 
182 
ps_threads(int pid,char * namefilter)183 void ps_threads(int pid, char *namefilter)
184 {
185     char tmp[128];
186     DIR *d;
187     struct dirent *de;
188 
189     sprintf(tmp,"/proc/%d/task",pid);
190     d = opendir(tmp);
191     if(d == 0) return;
192 
193     while((de = readdir(d)) != 0){
194         if(isdigit(de->d_name[0])){
195             int tid = atoi(de->d_name);
196             if(tid == pid) continue;
197             ps_line(pid, tid, namefilter);
198         }
199     }
200     closedir(d);
201 }
202 
ps_main(int argc,char ** argv)203 int ps_main(int argc, char **argv)
204 {
205     DIR *d;
206     struct dirent *de;
207     char *namefilter = 0;
208     int pidfilter = 0;
209     int threads = 0;
210 
211     d = opendir("/proc");
212     if(d == 0) return -1;
213 
214     while(argc > 1){
215         if(!strcmp(argv[1],"-t")) {
216             threads = 1;
217         } else if(!strcmp(argv[1],"-x")) {
218             display_flags |= SHOW_TIME;
219         } else if(!strcmp(argv[1], "-Z")) {
220             display_flags |= SHOW_MACLABEL;
221         } else if(!strcmp(argv[1],"-P")) {
222             display_flags |= SHOW_POLICY;
223         } else if(!strcmp(argv[1],"-p")) {
224             display_flags |= SHOW_PRIO;
225         } else if(!strcmp(argv[1],"-c")) {
226             display_flags |= SHOW_CPU;
227         }  else if(isdigit(argv[1][0])){
228             pidfilter = atoi(argv[1]);
229         } else {
230             namefilter = argv[1];
231         }
232         argc--;
233         argv++;
234     }
235 
236     if (display_flags & SHOW_MACLABEL) {
237         printf("LABEL                          USER     PID   PPID  NAME\n");
238     } else {
239         printf("USER     PID   PPID  VSIZE  RSS   %s%s %s WCHAN    PC         NAME\n",
240                (display_flags&SHOW_CPU)?"CPU ":"",
241                (display_flags&SHOW_PRIO)?"PRIO  NICE  RTPRI SCHED ":"",
242                (display_flags&SHOW_POLICY)?"PCY " : "");
243     }
244     while((de = readdir(d)) != 0){
245         if(isdigit(de->d_name[0])){
246             int pid = atoi(de->d_name);
247             if(!pidfilter || (pidfilter == pid)) {
248                 ps_line(pid, 0, namefilter);
249                 if(threads) ps_threads(pid, namefilter);
250             }
251         }
252     }
253     closedir(d);
254     return 0;
255 }
256 
257