blob: d0a8db35ec7c5981ab2164c04cba508b9cf16e30 [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
32static int display_flags = 0;
Elliott Hughesb5fc3132015-01-29 17:20:47 -080033static int ppid_filter = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080034
Kenny Root8f197e62014-05-14 15:07:08 -070035static void print_exe_abi(int pid);
36
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080037static int ps_line(int pid, int tid, char *namefilter)
38{
39 char statline[1024];
40 char cmdline[1024];
Stephen Smalley8290d102012-01-13 08:53:56 -050041 char macline[1024];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080042 char user[32];
43 struct stat stats;
44 int fd, r;
45 char *ptr, *name, *state;
Mark Salyzynaa907762014-05-08 09:31:43 -070046 int ppid;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080047 unsigned wchan, rss, vss, eip;
48 unsigned utime, stime;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -070049 int prio, nice, rtprio, sched, psr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080050 struct passwd *pw;
Marco Nelissen377cb2a2013-10-25 08:13:46 -070051
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080052 sprintf(statline, "/proc/%d", pid);
53 stat(statline, &stats);
54
55 if(tid) {
56 sprintf(statline, "/proc/%d/task/%d/stat", pid, tid);
57 cmdline[0] = 0;
Stephen Smalley8290d102012-01-13 08:53:56 -050058 snprintf(macline, sizeof(macline), "/proc/%d/task/%d/attr/current", pid, tid);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080059 } else {
60 sprintf(statline, "/proc/%d/stat", pid);
Stephen Smalley8290d102012-01-13 08:53:56 -050061 sprintf(cmdline, "/proc/%d/cmdline", pid);
62 snprintf(macline, sizeof(macline), "/proc/%d/attr/current", pid);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080063 fd = open(cmdline, O_RDONLY);
64 if(fd == 0) {
65 r = 0;
66 } else {
67 r = read(fd, cmdline, 1023);
68 close(fd);
69 if(r < 0) r = 0;
70 }
71 cmdline[r] = 0;
72 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -070073
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080074 fd = open(statline, O_RDONLY);
75 if(fd == 0) return -1;
76 r = read(fd, statline, 1023);
77 close(fd);
78 if(r < 0) return -1;
79 statline[r] = 0;
80
81 ptr = statline;
82 nexttok(&ptr); // skip pid
83 ptr++; // skip "("
84
85 name = ptr;
86 ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')',
87 *ptr++ = '\0'; // and null-terminate name.
88
89 ptr++; // skip " "
90 state = nexttok(&ptr);
91 ppid = atoi(nexttok(&ptr));
92 nexttok(&ptr); // pgrp
93 nexttok(&ptr); // sid
Mark Salyzynaa907762014-05-08 09:31:43 -070094 nexttok(&ptr); // tty
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080095 nexttok(&ptr); // tpgid
96 nexttok(&ptr); // flags
97 nexttok(&ptr); // minflt
98 nexttok(&ptr); // cminflt
99 nexttok(&ptr); // majflt
100 nexttok(&ptr); // cmajflt
101#if 1
102 utime = atoi(nexttok(&ptr));
103 stime = atoi(nexttok(&ptr));
104#else
105 nexttok(&ptr); // utime
106 nexttok(&ptr); // stime
107#endif
108 nexttok(&ptr); // cutime
109 nexttok(&ptr); // cstime
110 prio = atoi(nexttok(&ptr));
111 nice = atoi(nexttok(&ptr));
112 nexttok(&ptr); // threads
113 nexttok(&ptr); // itrealvalue
114 nexttok(&ptr); // starttime
115 vss = strtoul(nexttok(&ptr), 0, 10); // vsize
116 rss = strtoul(nexttok(&ptr), 0, 10); // rss
117 nexttok(&ptr); // rlim
118 nexttok(&ptr); // startcode
119 nexttok(&ptr); // endcode
120 nexttok(&ptr); // startstack
121 nexttok(&ptr); // kstkesp
122 eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip
123 nexttok(&ptr); // signal
124 nexttok(&ptr); // blocked
125 nexttok(&ptr); // sigignore
126 nexttok(&ptr); // sigcatch
127 wchan = strtoul(nexttok(&ptr), 0, 10); // wchan
128 nexttok(&ptr); // nswap
129 nexttok(&ptr); // cnswap
130 nexttok(&ptr); // exit signal
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700131 psr = atoi(nexttok(&ptr)); // processor
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800132 rtprio = atoi(nexttok(&ptr)); // rt_priority
133 sched = atoi(nexttok(&ptr)); // scheduling policy
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700134
Mark Salyzynaa907762014-05-08 09:31:43 -0700135 nexttok(&ptr); // tty
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700136
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800137 if(tid != 0) {
138 ppid = pid;
139 pid = tid;
140 }
141
142 pw = getpwuid(stats.st_uid);
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700143 if(pw == 0 || (display_flags & SHOW_NUMERIC_UID)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800144 sprintf(user,"%d",(int)stats.st_uid);
145 } else {
146 strcpy(user,pw->pw_name);
147 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700148
Elliott Hughesb5fc3132015-01-29 17:20:47 -0800149 if(ppid_filter != 0 && ppid != ppid_filter) {
150 return 0;
151 }
152
Dmitriy Ivanov65267bc2014-11-03 01:28:31 -0800153 if(!namefilter || !strncmp(cmdline[0] ? cmdline : name, namefilter, strlen(namefilter))) {
Stephen Smalley8290d102012-01-13 08:53:56 -0500154 if (display_flags & SHOW_MACLABEL) {
155 fd = open(macline, O_RDONLY);
156 strcpy(macline, "-");
157 if (fd >= 0) {
158 r = read(fd, macline, sizeof(macline)-1);
159 close(fd);
160 if (r > 0)
161 macline[r] = 0;
162 }
163 printf("%-30s %-9s %-5d %-5d %s\n", macline, user, pid, ppid, cmdline[0] ? cmdline : name);
164 return 0;
165 }
166
San Mehat39274412009-10-27 11:53:22 -0700167 printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4);
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700168 if (display_flags & SHOW_CPU)
169 printf(" %-2d", psr);
170 if (display_flags & SHOW_PRIO)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800171 printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched);
San Mehat39274412009-10-27 11:53:22 -0700172 if (display_flags & SHOW_POLICY) {
173 SchedPolicy p;
174 if (get_sched_policy(pid, &p) < 0)
175 printf(" un ");
Glenn Kasten86c7cc82012-03-05 16:14:39 -0800176 else
177 printf(" %.2s ", get_sched_policy_name(p));
San Mehat39274412009-10-27 11:53:22 -0700178 }
Kenny Root8f197e62014-05-14 15:07:08 -0700179 printf(" %08x %08x %s ", wchan, eip, state);
180 if (display_flags & SHOW_ABI) {
181 print_exe_abi(pid);
182 }
183 printf("%s", cmdline[0] ? cmdline : name);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800184 if(display_flags&SHOW_TIME)
185 printf(" (u:%d, s:%d)", utime, stime);
San Mehat39274412009-10-27 11:53:22 -0700186
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800187 printf("\n");
188 }
189 return 0;
190}
191
Kenny Root8f197e62014-05-14 15:07:08 -0700192static void print_exe_abi(int pid)
193{
194 int fd, r;
195 char exeline[1024];
196
197 sprintf(exeline, "/proc/%d/exe", pid);
198 fd = open(exeline, O_RDONLY);
199 if(fd == 0) {
200 printf(" ");
201 return;
202 }
203 r = read(fd, exeline, 5 /* 4 byte ELFMAG + 1 byte EI_CLASS */);
204 close(fd);
205 if(r < 0) {
206 printf(" ");
207 return;
208 }
209 if (memcmp("\177ELF", exeline, 4) != 0) {
210 printf("?? ");
211 return;
212 }
213 switch (exeline[4]) {
214 case 1:
215 printf("32 ");
216 return;
217 case 2:
218 printf("64 ");
219 return;
220 default:
221 printf("?? ");
222 return;
223 }
224}
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800225
226void ps_threads(int pid, char *namefilter)
227{
228 char tmp[128];
229 DIR *d;
230 struct dirent *de;
231
232 sprintf(tmp,"/proc/%d/task",pid);
233 d = opendir(tmp);
234 if(d == 0) return;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700235
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800236 while((de = readdir(d)) != 0){
237 if(isdigit(de->d_name[0])){
238 int tid = atoi(de->d_name);
239 if(tid == pid) continue;
240 ps_line(pid, tid, namefilter);
241 }
242 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700243 closedir(d);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800244}
245
246int ps_main(int argc, char **argv)
247{
248 DIR *d;
249 struct dirent *de;
250 char *namefilter = 0;
251 int pidfilter = 0;
252 int threads = 0;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700253
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800254 d = opendir("/proc");
255 if(d == 0) return -1;
256
257 while(argc > 1){
258 if(!strcmp(argv[1],"-t")) {
259 threads = 1;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700260 } else if(!strcmp(argv[1],"-n")) {
261 display_flags |= SHOW_NUMERIC_UID;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800262 } else if(!strcmp(argv[1],"-x")) {
263 display_flags |= SHOW_TIME;
Stephen Smalley8290d102012-01-13 08:53:56 -0500264 } else if(!strcmp(argv[1], "-Z")) {
265 display_flags |= SHOW_MACLABEL;
San Mehat39274412009-10-27 11:53:22 -0700266 } else if(!strcmp(argv[1],"-P")) {
267 display_flags |= SHOW_POLICY;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800268 } else if(!strcmp(argv[1],"-p")) {
269 display_flags |= SHOW_PRIO;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700270 } else if(!strcmp(argv[1],"-c")) {
271 display_flags |= SHOW_CPU;
Kenny Root8f197e62014-05-14 15:07:08 -0700272 } else if(!strcmp(argv[1],"--abi")) {
273 display_flags |= SHOW_ABI;
Elliott Hughesb5fc3132015-01-29 17:20:47 -0800274 } else if(!strcmp(argv[1],"--ppid")) {
275 ppid_filter = atoi(argv[2]);
276 argc--;
277 argv++;
Kenny Root8f197e62014-05-14 15:07:08 -0700278 } else if(isdigit(argv[1][0])){
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800279 pidfilter = atoi(argv[1]);
280 } else {
281 namefilter = argv[1];
282 }
283 argc--;
284 argv++;
285 }
286
Stephen Smalley8290d102012-01-13 08:53:56 -0500287 if (display_flags & SHOW_MACLABEL) {
288 printf("LABEL USER PID PPID NAME\n");
289 } else {
Kenny Root8f197e62014-05-14 15:07:08 -0700290 printf("USER PID PPID VSIZE RSS %s%s %s WCHAN PC %sNAME\n",
Stephen Smalley8290d102012-01-13 08:53:56 -0500291 (display_flags&SHOW_CPU)?"CPU ":"",
292 (display_flags&SHOW_PRIO)?"PRIO NICE RTPRI SCHED ":"",
Kenny Root8f197e62014-05-14 15:07:08 -0700293 (display_flags&SHOW_POLICY)?"PCY " : "",
294 (display_flags&SHOW_ABI)?"ABI " : "");
Stephen Smalley8290d102012-01-13 08:53:56 -0500295 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800296 while((de = readdir(d)) != 0){
297 if(isdigit(de->d_name[0])){
298 int pid = atoi(de->d_name);
299 if(!pidfilter || (pidfilter == pid)) {
300 ps_line(pid, 0, namefilter);
301 if(threads) ps_threads(pid, namefilter);
302 }
303 }
304 }
305 closedir(d);
306 return 0;
307}
308