blob: c68438b50f84d0df1418bf92a711538e459e4033 [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
Marco Nelissen377cb2a2013-10-25 08:13:46 -070031#define SHOW_NUMERIC_UID 32
Kenny Root7c015852014-05-14 17:29:21 -070032#define SHOW_ABI 64
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080033
34static int display_flags = 0;
35
Kenny Root8f197e62014-05-14 15:07:08 -070036static void print_exe_abi(int pid);
37
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080038static int ps_line(int pid, int tid, char *namefilter)
39{
40 char statline[1024];
41 char cmdline[1024];
Stephen Smalley8290d102012-01-13 08:53:56 -050042 char macline[1024];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080043 char user[32];
44 struct stat stats;
45 int fd, r;
46 char *ptr, *name, *state;
47 int ppid, tty;
48 unsigned wchan, rss, vss, eip;
49 unsigned utime, stime;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -070050 int prio, nice, rtprio, sched, psr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080051 struct passwd *pw;
Marco Nelissen377cb2a2013-10-25 08:13:46 -070052
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080053 sprintf(statline, "/proc/%d", pid);
54 stat(statline, &stats);
55
56 if(tid) {
57 sprintf(statline, "/proc/%d/task/%d/stat", pid, tid);
58 cmdline[0] = 0;
Stephen Smalley8290d102012-01-13 08:53:56 -050059 snprintf(macline, sizeof(macline), "/proc/%d/task/%d/attr/current", pid, tid);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080060 } else {
61 sprintf(statline, "/proc/%d/stat", pid);
Stephen Smalley8290d102012-01-13 08:53:56 -050062 sprintf(cmdline, "/proc/%d/cmdline", pid);
63 snprintf(macline, sizeof(macline), "/proc/%d/attr/current", pid);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080064 fd = open(cmdline, O_RDONLY);
65 if(fd == 0) {
66 r = 0;
67 } else {
68 r = read(fd, cmdline, 1023);
69 close(fd);
70 if(r < 0) r = 0;
71 }
72 cmdline[r] = 0;
73 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -070074
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080075 fd = open(statline, O_RDONLY);
76 if(fd == 0) return -1;
77 r = read(fd, statline, 1023);
78 close(fd);
79 if(r < 0) return -1;
80 statline[r] = 0;
81
82 ptr = statline;
83 nexttok(&ptr); // skip pid
84 ptr++; // skip "("
85
86 name = ptr;
87 ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')',
88 *ptr++ = '\0'; // and null-terminate name.
89
90 ptr++; // skip " "
91 state = nexttok(&ptr);
92 ppid = atoi(nexttok(&ptr));
93 nexttok(&ptr); // pgrp
94 nexttok(&ptr); // sid
95 tty = atoi(nexttok(&ptr));
Marco Nelissen377cb2a2013-10-25 08:13:46 -070096
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080097 nexttok(&ptr); // tpgid
98 nexttok(&ptr); // flags
99 nexttok(&ptr); // minflt
100 nexttok(&ptr); // cminflt
101 nexttok(&ptr); // majflt
102 nexttok(&ptr); // cmajflt
103#if 1
104 utime = atoi(nexttok(&ptr));
105 stime = atoi(nexttok(&ptr));
106#else
107 nexttok(&ptr); // utime
108 nexttok(&ptr); // stime
109#endif
110 nexttok(&ptr); // cutime
111 nexttok(&ptr); // cstime
112 prio = atoi(nexttok(&ptr));
113 nice = atoi(nexttok(&ptr));
114 nexttok(&ptr); // threads
115 nexttok(&ptr); // itrealvalue
116 nexttok(&ptr); // starttime
117 vss = strtoul(nexttok(&ptr), 0, 10); // vsize
118 rss = strtoul(nexttok(&ptr), 0, 10); // rss
119 nexttok(&ptr); // rlim
120 nexttok(&ptr); // startcode
121 nexttok(&ptr); // endcode
122 nexttok(&ptr); // startstack
123 nexttok(&ptr); // kstkesp
124 eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip
125 nexttok(&ptr); // signal
126 nexttok(&ptr); // blocked
127 nexttok(&ptr); // sigignore
128 nexttok(&ptr); // sigcatch
129 wchan = strtoul(nexttok(&ptr), 0, 10); // wchan
130 nexttok(&ptr); // nswap
131 nexttok(&ptr); // cnswap
132 nexttok(&ptr); // exit signal
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700133 psr = atoi(nexttok(&ptr)); // processor
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800134 rtprio = atoi(nexttok(&ptr)); // rt_priority
135 sched = atoi(nexttok(&ptr)); // scheduling policy
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700136
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800137 tty = atoi(nexttok(&ptr));
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700138
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800139 if(tid != 0) {
140 ppid = pid;
141 pid = tid;
142 }
143
144 pw = getpwuid(stats.st_uid);
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700145 if(pw == 0 || (display_flags & SHOW_NUMERIC_UID)) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800146 sprintf(user,"%d",(int)stats.st_uid);
147 } else {
148 strcpy(user,pw->pw_name);
149 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700150
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800151 if(!namefilter || !strncmp(name, namefilter, strlen(namefilter))) {
Stephen Smalley8290d102012-01-13 08:53:56 -0500152 if (display_flags & SHOW_MACLABEL) {
153 fd = open(macline, O_RDONLY);
154 strcpy(macline, "-");
155 if (fd >= 0) {
156 r = read(fd, macline, sizeof(macline)-1);
157 close(fd);
158 if (r > 0)
159 macline[r] = 0;
160 }
161 printf("%-30s %-9s %-5d %-5d %s\n", macline, user, pid, ppid, cmdline[0] ? cmdline : name);
162 return 0;
163 }
164
San Mehat39274412009-10-27 11:53:22 -0700165 printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4);
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700166 if (display_flags & SHOW_CPU)
167 printf(" %-2d", psr);
168 if (display_flags & SHOW_PRIO)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800169 printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched);
San Mehat39274412009-10-27 11:53:22 -0700170 if (display_flags & SHOW_POLICY) {
171 SchedPolicy p;
172 if (get_sched_policy(pid, &p) < 0)
173 printf(" un ");
Glenn Kasten86c7cc82012-03-05 16:14:39 -0800174 else
175 printf(" %.2s ", get_sched_policy_name(p));
San Mehat39274412009-10-27 11:53:22 -0700176 }
Kenny Root8f197e62014-05-14 15:07:08 -0700177 printf(" %08x %08x %s ", wchan, eip, state);
178 if (display_flags & SHOW_ABI) {
179 print_exe_abi(pid);
180 }
181 printf("%s", cmdline[0] ? cmdline : name);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800182 if(display_flags&SHOW_TIME)
183 printf(" (u:%d, s:%d)", utime, stime);
San Mehat39274412009-10-27 11:53:22 -0700184
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800185 printf("\n");
186 }
187 return 0;
188}
189
Kenny Root8f197e62014-05-14 15:07:08 -0700190static void print_exe_abi(int pid)
191{
192 int fd, r;
193 char exeline[1024];
194
195 sprintf(exeline, "/proc/%d/exe", pid);
196 fd = open(exeline, O_RDONLY);
197 if(fd == 0) {
198 printf(" ");
199 return;
200 }
201 r = read(fd, exeline, 5 /* 4 byte ELFMAG + 1 byte EI_CLASS */);
202 close(fd);
203 if(r < 0) {
204 printf(" ");
205 return;
206 }
207 if (memcmp("\177ELF", exeline, 4) != 0) {
208 printf("?? ");
209 return;
210 }
211 switch (exeline[4]) {
212 case 1:
213 printf("32 ");
214 return;
215 case 2:
216 printf("64 ");
217 return;
218 default:
219 printf("?? ");
220 return;
221 }
222}
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800223
224void ps_threads(int pid, char *namefilter)
225{
226 char tmp[128];
227 DIR *d;
228 struct dirent *de;
229
230 sprintf(tmp,"/proc/%d/task",pid);
231 d = opendir(tmp);
232 if(d == 0) return;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700233
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800234 while((de = readdir(d)) != 0){
235 if(isdigit(de->d_name[0])){
236 int tid = atoi(de->d_name);
237 if(tid == pid) continue;
238 ps_line(pid, tid, namefilter);
239 }
240 }
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700241 closedir(d);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800242}
243
244int ps_main(int argc, char **argv)
245{
246 DIR *d;
247 struct dirent *de;
248 char *namefilter = 0;
249 int pidfilter = 0;
250 int threads = 0;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700251
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800252 d = opendir("/proc");
253 if(d == 0) return -1;
254
255 while(argc > 1){
256 if(!strcmp(argv[1],"-t")) {
257 threads = 1;
Marco Nelissen377cb2a2013-10-25 08:13:46 -0700258 } else if(!strcmp(argv[1],"-n")) {
259 display_flags |= SHOW_NUMERIC_UID;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800260 } else if(!strcmp(argv[1],"-x")) {
261 display_flags |= SHOW_TIME;
Stephen Smalley8290d102012-01-13 08:53:56 -0500262 } else if(!strcmp(argv[1], "-Z")) {
263 display_flags |= SHOW_MACLABEL;
San Mehat39274412009-10-27 11:53:22 -0700264 } else if(!strcmp(argv[1],"-P")) {
265 display_flags |= SHOW_POLICY;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800266 } else if(!strcmp(argv[1],"-p")) {
267 display_flags |= SHOW_PRIO;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700268 } else if(!strcmp(argv[1],"-c")) {
269 display_flags |= SHOW_CPU;
Kenny Root8f197e62014-05-14 15:07:08 -0700270 } else if(!strcmp(argv[1],"--abi")) {
271 display_flags |= SHOW_ABI;
272 } else if(isdigit(argv[1][0])){
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800273 pidfilter = atoi(argv[1]);
274 } else {
275 namefilter = argv[1];
276 }
277 argc--;
278 argv++;
279 }
280
Stephen Smalley8290d102012-01-13 08:53:56 -0500281 if (display_flags & SHOW_MACLABEL) {
282 printf("LABEL USER PID PPID NAME\n");
283 } else {
Kenny Root8f197e62014-05-14 15:07:08 -0700284 printf("USER PID PPID VSIZE RSS %s%s %s WCHAN PC %sNAME\n",
Stephen Smalley8290d102012-01-13 08:53:56 -0500285 (display_flags&SHOW_CPU)?"CPU ":"",
286 (display_flags&SHOW_PRIO)?"PRIO NICE RTPRI SCHED ":"",
Kenny Root8f197e62014-05-14 15:07:08 -0700287 (display_flags&SHOW_POLICY)?"PCY " : "",
288 (display_flags&SHOW_ABI)?"ABI " : "");
Stephen Smalley8290d102012-01-13 08:53:56 -0500289 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800290 while((de = readdir(d)) != 0){
291 if(isdigit(de->d_name[0])){
292 int pid = atoi(de->d_name);
293 if(!pidfilter || (pidfilter == pid)) {
294 ps_line(pid, 0, namefilter);
295 if(threads) ps_threads(pid, namefilter);
296 }
297 }
298 }
299 closedir(d);
300 return 0;
301}
302