blob: cf3f05a82e6099a9ad4769a083234c7e30480766 [file] [log] [blame]
Elliott Hughes0badbd62014-12-29 12:24:25 -08001#include <ctype.h>
2#include <dirent.h>
3#include <fcntl.h>
Elliott Hughes8ac94d32015-03-09 21:10:10 -07004#include <inttypes.h>
Elliott Hughes0badbd62014-12-29 12:24:25 -08005#include <pwd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08006#include <stdio.h>
7#include <stdlib.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08008#include <string.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08009#include <sys/stat.h>
10#include <sys/types.h>
Elliott Hughes0badbd62014-12-29 12:24:25 -080011#include <unistd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080012
San Mehat39274412009-10-27 11:53:22 -070013#include <cutils/sched_policy.h>
14
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080015static char *nexttoksep(char **strp, char *sep)
16{
17 char *p = strsep(strp,sep);
18 return (p == 0) ? "" : p;
19}
20static char *nexttok(char **strp)
21{
22 return nexttoksep(strp, " ");
23}
24
25#define SHOW_PRIO 1
26#define SHOW_TIME 2
San Mehat39274412009-10-27 11:53:22 -070027#define SHOW_POLICY 4
Dmitry Shmidt8b37c912010-08-18 17:26:26 -070028#define SHOW_CPU 8
Stephen Smalley8290d102012-01-13 08:53:56 -050029#define SHOW_MACLABEL 16
Marco Nelissen377cb2a2013-10-25 08:13:46 -070030#define SHOW_NUMERIC_UID 32
Kenny Root7c015852014-05-14 17:29:21 -070031#define SHOW_ABI 64
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080032
Chris Dearman08b34662015-03-09 18:36:23 -070033#if __LP64__
34#define PC_WIDTH 10 /* Realistically, the top bits will be 0, so don't waste space. */
35#else
36#define PC_WIDTH (2*sizeof(uintptr_t))
37#endif
38
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080039static int display_flags = 0;
Elliott Hughesb5fc3132015-01-29 17:20:47 -080040static int ppid_filter = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080041
Kenny Root8f197e62014-05-14 15:07:08 -070042static void print_exe_abi(int pid);
43
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080044static int ps_line(int pid, int tid, char *namefilter)
45{
46 char statline[1024];
47 char cmdline[1024];
Stephen Smalley8290d102012-01-13 08:53:56 -050048 char macline[1024];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080049 char user[32];
50 struct stat stats;
51 int fd, r;
52 char *ptr, *name, *state;
Mark Salyzynaa907762014-05-08 09:31:43 -070053 int ppid;
Chris Dearman08b34662015-03-09 18:36:23 -070054 unsigned rss, vss;
55 uintptr_t eip;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080056 unsigned utime, stime;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -070057 int prio, nice, rtprio, sched, psr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080058 struct passwd *pw;
Marco Nelissen377cb2a2013-10-25 08:13:46 -070059
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080060 sprintf(statline, "/proc/%d", pid);
61 stat(statline, &stats);
62
63 if(tid) {
64 sprintf(statline, "/proc/%d/task/%d/stat", pid, tid);
65 cmdline[0] = 0;
Stephen Smalley8290d102012-01-13 08:53:56 -050066 snprintf(macline, sizeof(macline), "/proc/%d/task/%d/attr/current", pid, tid);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080067 } else {
68 sprintf(statline, "/proc/%d/stat", pid);
Stephen Smalley8290d102012-01-13 08:53:56 -050069 sprintf(cmdline, "/proc/%d/cmdline", pid);
70 snprintf(macline, sizeof(macline), "/proc/%d/attr/current", pid);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080071 fd = open(cmdline, O_RDONLY);
72 if(fd == 0) {
73 r = 0;
74 } else {
75 r = read(fd, cmdline, 1023);
76 close(fd);
77 if(r < 0) r = 0;
78 }
79 cmdline[r] = 0;
80 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -070081
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080082 fd = open(statline, O_RDONLY);
83 if(fd == 0) return -1;
84 r = read(fd, statline, 1023);
85 close(fd);
86 if(r < 0) return -1;
87 statline[r] = 0;
88
89 ptr = statline;
90 nexttok(&ptr); // skip pid
91 ptr++; // skip "("
92
93 name = ptr;
94 ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')',
95 *ptr++ = '\0'; // and null-terminate name.
96
97 ptr++; // skip " "
98 state = nexttok(&ptr);
99 ppid = atoi(nexttok(&ptr));
100 nexttok(&ptr); // pgrp
101 nexttok(&ptr); // sid
Mark Salyzynaa907762014-05-08 09:31:43 -0700102 nexttok(&ptr); // tty
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800103 nexttok(&ptr); // tpgid
104 nexttok(&ptr); // flags
105 nexttok(&ptr); // minflt
106 nexttok(&ptr); // cminflt
107 nexttok(&ptr); // majflt
108 nexttok(&ptr); // cmajflt
109#if 1
110 utime = atoi(nexttok(&ptr));
111 stime = atoi(nexttok(&ptr));
112#else
113 nexttok(&ptr); // utime
114 nexttok(&ptr); // stime
115#endif
116 nexttok(&ptr); // cutime
117 nexttok(&ptr); // cstime
118 prio = atoi(nexttok(&ptr));
119 nice = atoi(nexttok(&ptr));
120 nexttok(&ptr); // threads
121 nexttok(&ptr); // itrealvalue
122 nexttok(&ptr); // starttime
123 vss = strtoul(nexttok(&ptr), 0, 10); // vsize
124 rss = strtoul(nexttok(&ptr), 0, 10); // rss
125 nexttok(&ptr); // rlim
126 nexttok(&ptr); // startcode
127 nexttok(&ptr); // endcode
128 nexttok(&ptr); // startstack
129 nexttok(&ptr); // kstkesp
130 eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip
131 nexttok(&ptr); // signal
132 nexttok(&ptr); // blocked
133 nexttok(&ptr); // sigignore
134 nexttok(&ptr); // sigcatch
Chris Dearman08b34662015-03-09 18:36:23 -0700135 nexttok(&ptr); // wchan
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800136 nexttok(&ptr); // nswap
137 nexttok(&ptr); // cnswap
138 nexttok(&ptr); // exit signal
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700139 psr = atoi(nexttok(&ptr)); // processor
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800140 rtprio = atoi(nexttok(&ptr)); // rt_priority
141 sched = atoi(nexttok(&ptr)); // scheduling policy
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700142
Mark Salyzynaa907762014-05-08 09:31:43 -0700143 nexttok(&ptr); // tty
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700144
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800145 if(tid != 0) {
146 ppid = pid;
147 pid = tid;
148 }
149
150 pw = getpwuid(stats.st_uid);
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700151 if(pw == 0 || (display_flags & SHOW_NUMERIC_UID)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800152 sprintf(user,"%d",(int)stats.st_uid);
153 } else {
154 strcpy(user,pw->pw_name);
155 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700156
Elliott Hughesb5fc3132015-01-29 17:20:47 -0800157 if(ppid_filter != 0 && ppid != ppid_filter) {
158 return 0;
159 }
160
Dmitriy Ivanov65267bc2014-11-03 01:28:31 -0800161 if(!namefilter || !strncmp(cmdline[0] ? cmdline : name, namefilter, strlen(namefilter))) {
Stephen Smalley8290d102012-01-13 08:53:56 -0500162 if (display_flags & SHOW_MACLABEL) {
163 fd = open(macline, O_RDONLY);
164 strcpy(macline, "-");
165 if (fd >= 0) {
166 r = read(fd, macline, sizeof(macline)-1);
167 close(fd);
168 if (r > 0)
169 macline[r] = 0;
170 }
171 printf("%-30s %-9s %-5d %-5d %s\n", macline, user, pid, ppid, cmdline[0] ? cmdline : name);
172 return 0;
173 }
174
San Mehat39274412009-10-27 11:53:22 -0700175 printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4);
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700176 if (display_flags & SHOW_CPU)
177 printf(" %-2d", psr);
178 if (display_flags & SHOW_PRIO)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800179 printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched);
San Mehat39274412009-10-27 11:53:22 -0700180 if (display_flags & SHOW_POLICY) {
181 SchedPolicy p;
182 if (get_sched_policy(pid, &p) < 0)
183 printf(" un ");
Glenn Kasten86c7cc82012-03-05 16:14:39 -0800184 else
185 printf(" %.2s ", get_sched_policy_name(p));
San Mehat39274412009-10-27 11:53:22 -0700186 }
Chris Dearman08b34662015-03-09 18:36:23 -0700187 char path[PATH_MAX];
188 snprintf(path, sizeof(path), "/proc/%d/wchan", pid);
189 char wchan[10];
190 int fd = open(path, O_RDONLY);
191 ssize_t wchan_len = read(fd, wchan, sizeof(wchan));
192 if (wchan_len == -1) {
193 wchan[wchan_len = 0] = '\0';
194 }
195 close(fd);
Elliott Hughes8ac94d32015-03-09 21:10:10 -0700196 printf(" %10.*s %0*" PRIxPTR " %s ", (int) wchan_len, wchan, (int) PC_WIDTH, eip, state);
Kenny Root8f197e62014-05-14 15:07:08 -0700197 if (display_flags & SHOW_ABI) {
198 print_exe_abi(pid);
199 }
200 printf("%s", cmdline[0] ? cmdline : name);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800201 if(display_flags&SHOW_TIME)
202 printf(" (u:%d, s:%d)", utime, stime);
San Mehat39274412009-10-27 11:53:22 -0700203
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800204 printf("\n");
205 }
206 return 0;
207}
208
Kenny Root8f197e62014-05-14 15:07:08 -0700209static void print_exe_abi(int pid)
210{
211 int fd, r;
212 char exeline[1024];
213
214 sprintf(exeline, "/proc/%d/exe", pid);
215 fd = open(exeline, O_RDONLY);
216 if(fd == 0) {
217 printf(" ");
218 return;
219 }
220 r = read(fd, exeline, 5 /* 4 byte ELFMAG + 1 byte EI_CLASS */);
221 close(fd);
222 if(r < 0) {
223 printf(" ");
224 return;
225 }
226 if (memcmp("\177ELF", exeline, 4) != 0) {
227 printf("?? ");
228 return;
229 }
230 switch (exeline[4]) {
231 case 1:
232 printf("32 ");
233 return;
234 case 2:
235 printf("64 ");
236 return;
237 default:
238 printf("?? ");
239 return;
240 }
241}
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800242
243void ps_threads(int pid, char *namefilter)
244{
245 char tmp[128];
246 DIR *d;
247 struct dirent *de;
248
249 sprintf(tmp,"/proc/%d/task",pid);
250 d = opendir(tmp);
251 if(d == 0) return;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700252
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800253 while((de = readdir(d)) != 0){
254 if(isdigit(de->d_name[0])){
255 int tid = atoi(de->d_name);
256 if(tid == pid) continue;
257 ps_line(pid, tid, namefilter);
258 }
259 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700260 closedir(d);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800261}
262
263int ps_main(int argc, char **argv)
264{
265 DIR *d;
266 struct dirent *de;
267 char *namefilter = 0;
268 int pidfilter = 0;
269 int threads = 0;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700270
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800271 d = opendir("/proc");
272 if(d == 0) return -1;
273
274 while(argc > 1){
275 if(!strcmp(argv[1],"-t")) {
276 threads = 1;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700277 } else if(!strcmp(argv[1],"-n")) {
278 display_flags |= SHOW_NUMERIC_UID;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800279 } else if(!strcmp(argv[1],"-x")) {
280 display_flags |= SHOW_TIME;
Stephen Smalley8290d102012-01-13 08:53:56 -0500281 } else if(!strcmp(argv[1], "-Z")) {
282 display_flags |= SHOW_MACLABEL;
San Mehat39274412009-10-27 11:53:22 -0700283 } else if(!strcmp(argv[1],"-P")) {
284 display_flags |= SHOW_POLICY;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800285 } else if(!strcmp(argv[1],"-p")) {
286 display_flags |= SHOW_PRIO;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700287 } else if(!strcmp(argv[1],"-c")) {
288 display_flags |= SHOW_CPU;
Kenny Root8f197e62014-05-14 15:07:08 -0700289 } else if(!strcmp(argv[1],"--abi")) {
290 display_flags |= SHOW_ABI;
Elliott Hughesb5fc3132015-01-29 17:20:47 -0800291 } else if(!strcmp(argv[1],"--ppid")) {
292 ppid_filter = atoi(argv[2]);
293 argc--;
294 argv++;
Kenny Root8f197e62014-05-14 15:07:08 -0700295 } else if(isdigit(argv[1][0])){
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800296 pidfilter = atoi(argv[1]);
297 } else {
298 namefilter = argv[1];
299 }
300 argc--;
301 argv++;
302 }
303
Stephen Smalley8290d102012-01-13 08:53:56 -0500304 if (display_flags & SHOW_MACLABEL) {
Chris Dearman08b34662015-03-09 18:36:23 -0700305 printf("LABEL USER PID PPID NAME\n");
Stephen Smalley8290d102012-01-13 08:53:56 -0500306 } else {
Chris Dearman08b34662015-03-09 18:36:23 -0700307 printf("USER PID PPID VSIZE RSS %s%s %sWCHAN %*s %sNAME\n",
Stephen Smalley8290d102012-01-13 08:53:56 -0500308 (display_flags&SHOW_CPU)?"CPU ":"",
309 (display_flags&SHOW_PRIO)?"PRIO NICE RTPRI SCHED ":"",
Kenny Root8f197e62014-05-14 15:07:08 -0700310 (display_flags&SHOW_POLICY)?"PCY " : "",
Chris Dearman08b34662015-03-09 18:36:23 -0700311 (int) PC_WIDTH, "PC",
Kenny Root8f197e62014-05-14 15:07:08 -0700312 (display_flags&SHOW_ABI)?"ABI " : "");
Stephen Smalley8290d102012-01-13 08:53:56 -0500313 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800314 while((de = readdir(d)) != 0){
315 if(isdigit(de->d_name[0])){
316 int pid = atoi(de->d_name);
317 if(!pidfilter || (pidfilter == pid)) {
318 ps_line(pid, 0, namefilter);
319 if(threads) ps_threads(pid, namefilter);
320 }
321 }
322 }
323 closedir(d);
324 return 0;
325}
326