blob: 7d6dfa09694eecb8a22a9f27e2214efd372c4191 [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;
33
Kenny Root8f197e62014-05-14 15:07:08 -070034static void print_exe_abi(int pid);
35
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080036static int ps_line(int pid, int tid, char *namefilter)
37{
38 char statline[1024];
39 char cmdline[1024];
Stephen Smalley8290d102012-01-13 08:53:56 -050040 char macline[1024];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080041 char user[32];
42 struct stat stats;
43 int fd, r;
44 char *ptr, *name, *state;
Mark Salyzynaa907762014-05-08 09:31:43 -070045 int ppid;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080046 unsigned wchan, rss, vss, eip;
47 unsigned utime, stime;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -070048 int prio, nice, rtprio, sched, psr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080049 struct passwd *pw;
Marco Nelissen377cb2a2013-10-25 08:13:46 -070050
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080051 sprintf(statline, "/proc/%d", pid);
52 stat(statline, &stats);
53
54 if(tid) {
55 sprintf(statline, "/proc/%d/task/%d/stat", pid, tid);
56 cmdline[0] = 0;
Stephen Smalley8290d102012-01-13 08:53:56 -050057 snprintf(macline, sizeof(macline), "/proc/%d/task/%d/attr/current", pid, tid);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080058 } else {
59 sprintf(statline, "/proc/%d/stat", pid);
Stephen Smalley8290d102012-01-13 08:53:56 -050060 sprintf(cmdline, "/proc/%d/cmdline", pid);
61 snprintf(macline, sizeof(macline), "/proc/%d/attr/current", pid);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080062 fd = open(cmdline, O_RDONLY);
63 if(fd == 0) {
64 r = 0;
65 } else {
66 r = read(fd, cmdline, 1023);
67 close(fd);
68 if(r < 0) r = 0;
69 }
70 cmdline[r] = 0;
71 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -070072
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080073 fd = open(statline, O_RDONLY);
74 if(fd == 0) return -1;
75 r = read(fd, statline, 1023);
76 close(fd);
77 if(r < 0) return -1;
78 statline[r] = 0;
79
80 ptr = statline;
81 nexttok(&ptr); // skip pid
82 ptr++; // skip "("
83
84 name = ptr;
85 ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')',
86 *ptr++ = '\0'; // and null-terminate name.
87
88 ptr++; // skip " "
89 state = nexttok(&ptr);
90 ppid = atoi(nexttok(&ptr));
91 nexttok(&ptr); // pgrp
92 nexttok(&ptr); // sid
Mark Salyzynaa907762014-05-08 09:31:43 -070093 nexttok(&ptr); // tty
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080094 nexttok(&ptr); // tpgid
95 nexttok(&ptr); // flags
96 nexttok(&ptr); // minflt
97 nexttok(&ptr); // cminflt
98 nexttok(&ptr); // majflt
99 nexttok(&ptr); // cmajflt
100#if 1
101 utime = atoi(nexttok(&ptr));
102 stime = atoi(nexttok(&ptr));
103#else
104 nexttok(&ptr); // utime
105 nexttok(&ptr); // stime
106#endif
107 nexttok(&ptr); // cutime
108 nexttok(&ptr); // cstime
109 prio = atoi(nexttok(&ptr));
110 nice = atoi(nexttok(&ptr));
111 nexttok(&ptr); // threads
112 nexttok(&ptr); // itrealvalue
113 nexttok(&ptr); // starttime
114 vss = strtoul(nexttok(&ptr), 0, 10); // vsize
115 rss = strtoul(nexttok(&ptr), 0, 10); // rss
116 nexttok(&ptr); // rlim
117 nexttok(&ptr); // startcode
118 nexttok(&ptr); // endcode
119 nexttok(&ptr); // startstack
120 nexttok(&ptr); // kstkesp
121 eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip
122 nexttok(&ptr); // signal
123 nexttok(&ptr); // blocked
124 nexttok(&ptr); // sigignore
125 nexttok(&ptr); // sigcatch
126 wchan = strtoul(nexttok(&ptr), 0, 10); // wchan
127 nexttok(&ptr); // nswap
128 nexttok(&ptr); // cnswap
129 nexttok(&ptr); // exit signal
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700130 psr = atoi(nexttok(&ptr)); // processor
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800131 rtprio = atoi(nexttok(&ptr)); // rt_priority
132 sched = atoi(nexttok(&ptr)); // scheduling policy
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700133
Mark Salyzynaa907762014-05-08 09:31:43 -0700134 nexttok(&ptr); // tty
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700135
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800136 if(tid != 0) {
137 ppid = pid;
138 pid = tid;
139 }
140
141 pw = getpwuid(stats.st_uid);
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700142 if(pw == 0 || (display_flags & SHOW_NUMERIC_UID)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800143 sprintf(user,"%d",(int)stats.st_uid);
144 } else {
145 strcpy(user,pw->pw_name);
146 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700147
Dmitriy Ivanov65267bc2014-11-03 01:28:31 -0800148 if(!namefilter || !strncmp(cmdline[0] ? cmdline : name, namefilter, strlen(namefilter))) {
Stephen Smalley8290d102012-01-13 08:53:56 -0500149 if (display_flags & SHOW_MACLABEL) {
150 fd = open(macline, O_RDONLY);
151 strcpy(macline, "-");
152 if (fd >= 0) {
153 r = read(fd, macline, sizeof(macline)-1);
154 close(fd);
155 if (r > 0)
156 macline[r] = 0;
157 }
158 printf("%-30s %-9s %-5d %-5d %s\n", macline, user, pid, ppid, cmdline[0] ? cmdline : name);
159 return 0;
160 }
161
San Mehat39274412009-10-27 11:53:22 -0700162 printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4);
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700163 if (display_flags & SHOW_CPU)
164 printf(" %-2d", psr);
165 if (display_flags & SHOW_PRIO)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800166 printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched);
San Mehat39274412009-10-27 11:53:22 -0700167 if (display_flags & SHOW_POLICY) {
168 SchedPolicy p;
169 if (get_sched_policy(pid, &p) < 0)
170 printf(" un ");
Glenn Kasten86c7cc82012-03-05 16:14:39 -0800171 else
172 printf(" %.2s ", get_sched_policy_name(p));
San Mehat39274412009-10-27 11:53:22 -0700173 }
Kenny Root8f197e62014-05-14 15:07:08 -0700174 printf(" %08x %08x %s ", wchan, eip, state);
175 if (display_flags & SHOW_ABI) {
176 print_exe_abi(pid);
177 }
178 printf("%s", cmdline[0] ? cmdline : name);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800179 if(display_flags&SHOW_TIME)
180 printf(" (u:%d, s:%d)", utime, stime);
San Mehat39274412009-10-27 11:53:22 -0700181
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800182 printf("\n");
183 }
184 return 0;
185}
186
Kenny Root8f197e62014-05-14 15:07:08 -0700187static void print_exe_abi(int pid)
188{
189 int fd, r;
190 char exeline[1024];
191
192 sprintf(exeline, "/proc/%d/exe", pid);
193 fd = open(exeline, O_RDONLY);
194 if(fd == 0) {
195 printf(" ");
196 return;
197 }
198 r = read(fd, exeline, 5 /* 4 byte ELFMAG + 1 byte EI_CLASS */);
199 close(fd);
200 if(r < 0) {
201 printf(" ");
202 return;
203 }
204 if (memcmp("\177ELF", exeline, 4) != 0) {
205 printf("?? ");
206 return;
207 }
208 switch (exeline[4]) {
209 case 1:
210 printf("32 ");
211 return;
212 case 2:
213 printf("64 ");
214 return;
215 default:
216 printf("?? ");
217 return;
218 }
219}
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800220
221void ps_threads(int pid, char *namefilter)
222{
223 char tmp[128];
224 DIR *d;
225 struct dirent *de;
226
227 sprintf(tmp,"/proc/%d/task",pid);
228 d = opendir(tmp);
229 if(d == 0) return;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700230
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800231 while((de = readdir(d)) != 0){
232 if(isdigit(de->d_name[0])){
233 int tid = atoi(de->d_name);
234 if(tid == pid) continue;
235 ps_line(pid, tid, namefilter);
236 }
237 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700238 closedir(d);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800239}
240
241int ps_main(int argc, char **argv)
242{
243 DIR *d;
244 struct dirent *de;
245 char *namefilter = 0;
246 int pidfilter = 0;
247 int threads = 0;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700248
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800249 d = opendir("/proc");
250 if(d == 0) return -1;
251
252 while(argc > 1){
253 if(!strcmp(argv[1],"-t")) {
254 threads = 1;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700255 } else if(!strcmp(argv[1],"-n")) {
256 display_flags |= SHOW_NUMERIC_UID;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800257 } else if(!strcmp(argv[1],"-x")) {
258 display_flags |= SHOW_TIME;
Stephen Smalley8290d102012-01-13 08:53:56 -0500259 } else if(!strcmp(argv[1], "-Z")) {
260 display_flags |= SHOW_MACLABEL;
San Mehat39274412009-10-27 11:53:22 -0700261 } else if(!strcmp(argv[1],"-P")) {
262 display_flags |= SHOW_POLICY;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800263 } else if(!strcmp(argv[1],"-p")) {
264 display_flags |= SHOW_PRIO;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700265 } else if(!strcmp(argv[1],"-c")) {
266 display_flags |= SHOW_CPU;
Kenny Root8f197e62014-05-14 15:07:08 -0700267 } else if(!strcmp(argv[1],"--abi")) {
268 display_flags |= SHOW_ABI;
269 } else if(isdigit(argv[1][0])){
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800270 pidfilter = atoi(argv[1]);
271 } else {
272 namefilter = argv[1];
273 }
274 argc--;
275 argv++;
276 }
277
Stephen Smalley8290d102012-01-13 08:53:56 -0500278 if (display_flags & SHOW_MACLABEL) {
279 printf("LABEL USER PID PPID NAME\n");
280 } else {
Kenny Root8f197e62014-05-14 15:07:08 -0700281 printf("USER PID PPID VSIZE RSS %s%s %s WCHAN PC %sNAME\n",
Stephen Smalley8290d102012-01-13 08:53:56 -0500282 (display_flags&SHOW_CPU)?"CPU ":"",
283 (display_flags&SHOW_PRIO)?"PRIO NICE RTPRI SCHED ":"",
Kenny Root8f197e62014-05-14 15:07:08 -0700284 (display_flags&SHOW_POLICY)?"PCY " : "",
285 (display_flags&SHOW_ABI)?"ABI " : "");
Stephen Smalley8290d102012-01-13 08:53:56 -0500286 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800287 while((de = readdir(d)) != 0){
288 if(isdigit(de->d_name[0])){
289 int pid = atoi(de->d_name);
290 if(!pidfilter || (pidfilter == pid)) {
291 ps_line(pid, 0, namefilter);
292 if(threads) ps_threads(pid, namefilter);
293 }
294 }
295 }
296 closedir(d);
297 return 0;
298}
299