blob: 18129ff5547a2fcc0d1610fbb5d5800e5dc77858 [file] [log] [blame]
Elliott Hughes0badbd62014-12-29 12:24:25 -08001#include <ctype.h>
2#include <dirent.h>
3#include <fcntl.h>
4#include <pwd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08005#include <stdio.h>
6#include <stdlib.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08007#include <string.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08008#include <sys/stat.h>
9#include <sys/types.h>
Elliott Hughes0badbd62014-12-29 12:24:25 -080010#include <unistd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080011
San Mehat39274412009-10-27 11:53:22 -070012#include <cutils/sched_policy.h>
13
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080014static char *nexttoksep(char **strp, char *sep)
15{
16 char *p = strsep(strp,sep);
17 return (p == 0) ? "" : p;
18}
19static char *nexttok(char **strp)
20{
21 return nexttoksep(strp, " ");
22}
23
24#define SHOW_PRIO 1
25#define SHOW_TIME 2
San Mehat39274412009-10-27 11:53:22 -070026#define SHOW_POLICY 4
Dmitry Shmidt8b37c912010-08-18 17:26:26 -070027#define SHOW_CPU 8
Stephen Smalley8290d102012-01-13 08:53:56 -050028#define SHOW_MACLABEL 16
Marco Nelissen377cb2a2013-10-25 08:13:46 -070029#define SHOW_NUMERIC_UID 32
Kenny Root7c015852014-05-14 17:29:21 -070030#define SHOW_ABI 64
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080031
Chris Dearman08b34662015-03-09 18:36:23 -070032#if __LP64__
33#define PC_WIDTH 10 /* Realistically, the top bits will be 0, so don't waste space. */
34#else
35#define PC_WIDTH (2*sizeof(uintptr_t))
36#endif
37
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080038static int display_flags = 0;
Elliott Hughesb5fc3132015-01-29 17:20:47 -080039static int ppid_filter = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080040
Kenny Root8f197e62014-05-14 15:07:08 -070041static void print_exe_abi(int pid);
42
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080043static int ps_line(int pid, int tid, char *namefilter)
44{
45 char statline[1024];
46 char cmdline[1024];
Stephen Smalley8290d102012-01-13 08:53:56 -050047 char macline[1024];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080048 char user[32];
49 struct stat stats;
50 int fd, r;
51 char *ptr, *name, *state;
Mark Salyzynaa907762014-05-08 09:31:43 -070052 int ppid;
Chris Dearman08b34662015-03-09 18:36:23 -070053 unsigned rss, vss;
54 uintptr_t eip;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080055 unsigned utime, stime;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -070056 int prio, nice, rtprio, sched, psr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080057 struct passwd *pw;
Marco Nelissen377cb2a2013-10-25 08:13:46 -070058
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080059 sprintf(statline, "/proc/%d", pid);
60 stat(statline, &stats);
61
62 if(tid) {
63 sprintf(statline, "/proc/%d/task/%d/stat", pid, tid);
64 cmdline[0] = 0;
Stephen Smalley8290d102012-01-13 08:53:56 -050065 snprintf(macline, sizeof(macline), "/proc/%d/task/%d/attr/current", pid, tid);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080066 } else {
67 sprintf(statline, "/proc/%d/stat", pid);
Stephen Smalley8290d102012-01-13 08:53:56 -050068 sprintf(cmdline, "/proc/%d/cmdline", pid);
69 snprintf(macline, sizeof(macline), "/proc/%d/attr/current", pid);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080070 fd = open(cmdline, O_RDONLY);
71 if(fd == 0) {
72 r = 0;
73 } else {
74 r = read(fd, cmdline, 1023);
75 close(fd);
76 if(r < 0) r = 0;
77 }
78 cmdline[r] = 0;
79 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -070080
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080081 fd = open(statline, O_RDONLY);
82 if(fd == 0) return -1;
83 r = read(fd, statline, 1023);
84 close(fd);
85 if(r < 0) return -1;
86 statline[r] = 0;
87
88 ptr = statline;
89 nexttok(&ptr); // skip pid
90 ptr++; // skip "("
91
92 name = ptr;
93 ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')',
94 *ptr++ = '\0'; // and null-terminate name.
95
96 ptr++; // skip " "
97 state = nexttok(&ptr);
98 ppid = atoi(nexttok(&ptr));
99 nexttok(&ptr); // pgrp
100 nexttok(&ptr); // sid
Mark Salyzynaa907762014-05-08 09:31:43 -0700101 nexttok(&ptr); // tty
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800102 nexttok(&ptr); // tpgid
103 nexttok(&ptr); // flags
104 nexttok(&ptr); // minflt
105 nexttok(&ptr); // cminflt
106 nexttok(&ptr); // majflt
107 nexttok(&ptr); // cmajflt
108#if 1
109 utime = atoi(nexttok(&ptr));
110 stime = atoi(nexttok(&ptr));
111#else
112 nexttok(&ptr); // utime
113 nexttok(&ptr); // stime
114#endif
115 nexttok(&ptr); // cutime
116 nexttok(&ptr); // cstime
117 prio = atoi(nexttok(&ptr));
118 nice = atoi(nexttok(&ptr));
119 nexttok(&ptr); // threads
120 nexttok(&ptr); // itrealvalue
121 nexttok(&ptr); // starttime
122 vss = strtoul(nexttok(&ptr), 0, 10); // vsize
123 rss = strtoul(nexttok(&ptr), 0, 10); // rss
124 nexttok(&ptr); // rlim
125 nexttok(&ptr); // startcode
126 nexttok(&ptr); // endcode
127 nexttok(&ptr); // startstack
128 nexttok(&ptr); // kstkesp
129 eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip
130 nexttok(&ptr); // signal
131 nexttok(&ptr); // blocked
132 nexttok(&ptr); // sigignore
133 nexttok(&ptr); // sigcatch
Chris Dearman08b34662015-03-09 18:36:23 -0700134 nexttok(&ptr); // wchan
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800135 nexttok(&ptr); // nswap
136 nexttok(&ptr); // cnswap
137 nexttok(&ptr); // exit signal
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700138 psr = atoi(nexttok(&ptr)); // processor
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800139 rtprio = atoi(nexttok(&ptr)); // rt_priority
140 sched = atoi(nexttok(&ptr)); // scheduling policy
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700141
Mark Salyzynaa907762014-05-08 09:31:43 -0700142 nexttok(&ptr); // tty
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700143
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800144 if(tid != 0) {
145 ppid = pid;
146 pid = tid;
147 }
148
149 pw = getpwuid(stats.st_uid);
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700150 if(pw == 0 || (display_flags & SHOW_NUMERIC_UID)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800151 sprintf(user,"%d",(int)stats.st_uid);
152 } else {
153 strcpy(user,pw->pw_name);
154 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700155
Elliott Hughesb5fc3132015-01-29 17:20:47 -0800156 if(ppid_filter != 0 && ppid != ppid_filter) {
157 return 0;
158 }
159
Dmitriy Ivanov65267bc2014-11-03 01:28:31 -0800160 if(!namefilter || !strncmp(cmdline[0] ? cmdline : name, namefilter, strlen(namefilter))) {
Stephen Smalley8290d102012-01-13 08:53:56 -0500161 if (display_flags & SHOW_MACLABEL) {
162 fd = open(macline, O_RDONLY);
163 strcpy(macline, "-");
164 if (fd >= 0) {
165 r = read(fd, macline, sizeof(macline)-1);
166 close(fd);
167 if (r > 0)
168 macline[r] = 0;
169 }
170 printf("%-30s %-9s %-5d %-5d %s\n", macline, user, pid, ppid, cmdline[0] ? cmdline : name);
171 return 0;
172 }
173
San Mehat39274412009-10-27 11:53:22 -0700174 printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4);
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700175 if (display_flags & SHOW_CPU)
176 printf(" %-2d", psr);
177 if (display_flags & SHOW_PRIO)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800178 printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched);
San Mehat39274412009-10-27 11:53:22 -0700179 if (display_flags & SHOW_POLICY) {
180 SchedPolicy p;
181 if (get_sched_policy(pid, &p) < 0)
182 printf(" un ");
Glenn Kasten86c7cc82012-03-05 16:14:39 -0800183 else
184 printf(" %.2s ", get_sched_policy_name(p));
San Mehat39274412009-10-27 11:53:22 -0700185 }
Chris Dearman08b34662015-03-09 18:36:23 -0700186 char path[PATH_MAX];
187 snprintf(path, sizeof(path), "/proc/%d/wchan", pid);
188 char wchan[10];
189 int fd = open(path, O_RDONLY);
190 ssize_t wchan_len = read(fd, wchan, sizeof(wchan));
191 if (wchan_len == -1) {
192 wchan[wchan_len = 0] = '\0';
193 }
194 close(fd);
195 printf(" %10.*s %0*lx %s ", (int) wchan_len, wchan, (int) PC_WIDTH, eip, state);
Kenny Root8f197e62014-05-14 15:07:08 -0700196 if (display_flags & SHOW_ABI) {
197 print_exe_abi(pid);
198 }
199 printf("%s", cmdline[0] ? cmdline : name);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800200 if(display_flags&SHOW_TIME)
201 printf(" (u:%d, s:%d)", utime, stime);
San Mehat39274412009-10-27 11:53:22 -0700202
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800203 printf("\n");
204 }
205 return 0;
206}
207
Kenny Root8f197e62014-05-14 15:07:08 -0700208static void print_exe_abi(int pid)
209{
210 int fd, r;
211 char exeline[1024];
212
213 sprintf(exeline, "/proc/%d/exe", pid);
214 fd = open(exeline, O_RDONLY);
215 if(fd == 0) {
216 printf(" ");
217 return;
218 }
219 r = read(fd, exeline, 5 /* 4 byte ELFMAG + 1 byte EI_CLASS */);
220 close(fd);
221 if(r < 0) {
222 printf(" ");
223 return;
224 }
225 if (memcmp("\177ELF", exeline, 4) != 0) {
226 printf("?? ");
227 return;
228 }
229 switch (exeline[4]) {
230 case 1:
231 printf("32 ");
232 return;
233 case 2:
234 printf("64 ");
235 return;
236 default:
237 printf("?? ");
238 return;
239 }
240}
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800241
242void ps_threads(int pid, char *namefilter)
243{
244 char tmp[128];
245 DIR *d;
246 struct dirent *de;
247
248 sprintf(tmp,"/proc/%d/task",pid);
249 d = opendir(tmp);
250 if(d == 0) return;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700251
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800252 while((de = readdir(d)) != 0){
253 if(isdigit(de->d_name[0])){
254 int tid = atoi(de->d_name);
255 if(tid == pid) continue;
256 ps_line(pid, tid, namefilter);
257 }
258 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700259 closedir(d);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800260}
261
262int ps_main(int argc, char **argv)
263{
264 DIR *d;
265 struct dirent *de;
266 char *namefilter = 0;
267 int pidfilter = 0;
268 int threads = 0;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700269
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800270 d = opendir("/proc");
271 if(d == 0) return -1;
272
273 while(argc > 1){
274 if(!strcmp(argv[1],"-t")) {
275 threads = 1;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700276 } else if(!strcmp(argv[1],"-n")) {
277 display_flags |= SHOW_NUMERIC_UID;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800278 } else if(!strcmp(argv[1],"-x")) {
279 display_flags |= SHOW_TIME;
Stephen Smalley8290d102012-01-13 08:53:56 -0500280 } else if(!strcmp(argv[1], "-Z")) {
281 display_flags |= SHOW_MACLABEL;
San Mehat39274412009-10-27 11:53:22 -0700282 } else if(!strcmp(argv[1],"-P")) {
283 display_flags |= SHOW_POLICY;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800284 } else if(!strcmp(argv[1],"-p")) {
285 display_flags |= SHOW_PRIO;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700286 } else if(!strcmp(argv[1],"-c")) {
287 display_flags |= SHOW_CPU;
Kenny Root8f197e62014-05-14 15:07:08 -0700288 } else if(!strcmp(argv[1],"--abi")) {
289 display_flags |= SHOW_ABI;
Elliott Hughesb5fc3132015-01-29 17:20:47 -0800290 } else if(!strcmp(argv[1],"--ppid")) {
291 ppid_filter = atoi(argv[2]);
292 argc--;
293 argv++;
Kenny Root8f197e62014-05-14 15:07:08 -0700294 } else if(isdigit(argv[1][0])){
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800295 pidfilter = atoi(argv[1]);
296 } else {
297 namefilter = argv[1];
298 }
299 argc--;
300 argv++;
301 }
302
Stephen Smalley8290d102012-01-13 08:53:56 -0500303 if (display_flags & SHOW_MACLABEL) {
Chris Dearman08b34662015-03-09 18:36:23 -0700304 printf("LABEL USER PID PPID NAME\n");
Stephen Smalley8290d102012-01-13 08:53:56 -0500305 } else {
Chris Dearman08b34662015-03-09 18:36:23 -0700306 printf("USER PID PPID VSIZE RSS %s%s %sWCHAN %*s %sNAME\n",
Stephen Smalley8290d102012-01-13 08:53:56 -0500307 (display_flags&SHOW_CPU)?"CPU ":"",
308 (display_flags&SHOW_PRIO)?"PRIO NICE RTPRI SCHED ":"",
Kenny Root8f197e62014-05-14 15:07:08 -0700309 (display_flags&SHOW_POLICY)?"PCY " : "",
Chris Dearman08b34662015-03-09 18:36:23 -0700310 (int) PC_WIDTH, "PC",
Kenny Root8f197e62014-05-14 15:07:08 -0700311 (display_flags&SHOW_ABI)?"ABI " : "");
Stephen Smalley8290d102012-01-13 08:53:56 -0500312 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800313 while((de = readdir(d)) != 0){
314 if(isdigit(de->d_name[0])){
315 int pid = atoi(de->d_name);
316 if(!pidfilter || (pidfilter == pid)) {
317 ps_line(pid, 0, namefilter);
318 if(threads) ps_threads(pid, namefilter);
319 }
320 }
321 }
322 closedir(d);
323 return 0;
324}
325