blob: 7c35ccb4894c519ad54e3d35c3eb9c6bd6af7a51 [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001#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
San Mehat39274412009-10-27 11:53:22 -070014#include <cutils/sched_policy.h>
15
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080016static char *nexttoksep(char **strp, char *sep)
17{
18 char *p = strsep(strp,sep);
19 return (p == 0) ? "" : p;
20}
21static char *nexttok(char **strp)
22{
23 return nexttoksep(strp, " ");
24}
25
26#define SHOW_PRIO 1
27#define SHOW_TIME 2
San Mehat39274412009-10-27 11:53:22 -070028#define SHOW_POLICY 4
Dmitry Shmidt8b37c912010-08-18 17:26:26 -070029#define SHOW_CPU 8
Stephen Smalley8290d102012-01-13 08:53:56 -050030#define SHOW_MACLABEL 16
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080031
32static int display_flags = 0;
33
34static int ps_line(int pid, int tid, char *namefilter)
35{
36 char statline[1024];
37 char cmdline[1024];
Stephen Smalley8290d102012-01-13 08:53:56 -050038 char macline[1024];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080039 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;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -070046 int prio, nice, rtprio, sched, psr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080047 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;
Stephen Smalley8290d102012-01-13 08:53:56 -050055 snprintf(macline, sizeof(macline), "/proc/%d/task/%d/attr/current", pid, tid);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080056 } else {
57 sprintf(statline, "/proc/%d/stat", pid);
Stephen Smalley8290d102012-01-13 08:53:56 -050058 sprintf(cmdline, "/proc/%d/cmdline", pid);
59 snprintf(macline, sizeof(macline), "/proc/%d/attr/current", pid);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080060 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
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700129 psr = atoi(nexttok(&ptr)); // processor
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800130 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))) {
Stephen Smalley8290d102012-01-13 08:53:56 -0500148 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
San Mehat39274412009-10-27 11:53:22 -0700161 printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4);
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700162 if (display_flags & SHOW_CPU)
163 printf(" %-2d", psr);
164 if (display_flags & SHOW_PRIO)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800165 printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched);
San Mehat39274412009-10-27 11:53:22 -0700166 if (display_flags & SHOW_POLICY) {
167 SchedPolicy p;
168 if (get_sched_policy(pid, &p) < 0)
169 printf(" un ");
Glenn Kasten86c7cc82012-03-05 16:14:39 -0800170 else
171 printf(" %.2s ", get_sched_policy_name(p));
San Mehat39274412009-10-27 11:53:22 -0700172 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800173 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);
San Mehat39274412009-10-27 11:53:22 -0700176
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800177 printf("\n");
178 }
179 return 0;
180}
181
182
183void 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
203int 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;
Stephen Smalley8290d102012-01-13 08:53:56 -0500219 } else if(!strcmp(argv[1], "-Z")) {
220 display_flags |= SHOW_MACLABEL;
San Mehat39274412009-10-27 11:53:22 -0700221 } else if(!strcmp(argv[1],"-P")) {
222 display_flags |= SHOW_POLICY;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800223 } else if(!strcmp(argv[1],"-p")) {
224 display_flags |= SHOW_PRIO;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700225 } else if(!strcmp(argv[1],"-c")) {
226 display_flags |= SHOW_CPU;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800227 } else if(isdigit(argv[1][0])){
228 pidfilter = atoi(argv[1]);
229 } else {
230 namefilter = argv[1];
231 }
232 argc--;
233 argv++;
234 }
235
Stephen Smalley8290d102012-01-13 08:53:56 -0500236 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 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800244 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