blob: 2aa3efb5639b1ddf7a1464b80cd87c7c3a3848aa [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 -080016
17static char *nexttoksep(char **strp, char *sep)
18{
19 char *p = strsep(strp,sep);
20 return (p == 0) ? "" : p;
21}
22static char *nexttok(char **strp)
23{
24 return nexttoksep(strp, " ");
25}
26
27#define SHOW_PRIO 1
28#define SHOW_TIME 2
San Mehat39274412009-10-27 11:53:22 -070029#define SHOW_POLICY 4
Dmitry Shmidt8b37c912010-08-18 17:26:26 -070030#define SHOW_CPU 8
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080031
32static int display_flags = 0;
33
34static int ps_line(int pid, int tid, char *namefilter)
35{
36 char statline[1024];
37 char cmdline[1024];
38 char user[32];
39 struct stat stats;
40 int fd, r;
41 char *ptr, *name, *state;
42 int ppid, tty;
43 unsigned wchan, rss, vss, eip;
44 unsigned utime, stime;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -070045 int prio, nice, rtprio, sched, psr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080046 struct passwd *pw;
47
48 sprintf(statline, "/proc/%d", pid);
49 stat(statline, &stats);
50
51 if(tid) {
52 sprintf(statline, "/proc/%d/task/%d/stat", pid, tid);
53 cmdline[0] = 0;
54 } else {
55 sprintf(statline, "/proc/%d/stat", pid);
56 sprintf(cmdline, "/proc/%d/cmdline", pid);
57 fd = open(cmdline, O_RDONLY);
58 if(fd == 0) {
59 r = 0;
60 } else {
61 r = read(fd, cmdline, 1023);
62 close(fd);
63 if(r < 0) r = 0;
64 }
65 cmdline[r] = 0;
66 }
67
68 fd = open(statline, O_RDONLY);
69 if(fd == 0) return -1;
70 r = read(fd, statline, 1023);
71 close(fd);
72 if(r < 0) return -1;
73 statline[r] = 0;
74
75 ptr = statline;
76 nexttok(&ptr); // skip pid
77 ptr++; // skip "("
78
79 name = ptr;
80 ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')',
81 *ptr++ = '\0'; // and null-terminate name.
82
83 ptr++; // skip " "
84 state = nexttok(&ptr);
85 ppid = atoi(nexttok(&ptr));
86 nexttok(&ptr); // pgrp
87 nexttok(&ptr); // sid
88 tty = atoi(nexttok(&ptr));
89
90 nexttok(&ptr); // tpgid
91 nexttok(&ptr); // flags
92 nexttok(&ptr); // minflt
93 nexttok(&ptr); // cminflt
94 nexttok(&ptr); // majflt
95 nexttok(&ptr); // cmajflt
96#if 1
97 utime = atoi(nexttok(&ptr));
98 stime = atoi(nexttok(&ptr));
99#else
100 nexttok(&ptr); // utime
101 nexttok(&ptr); // stime
102#endif
103 nexttok(&ptr); // cutime
104 nexttok(&ptr); // cstime
105 prio = atoi(nexttok(&ptr));
106 nice = atoi(nexttok(&ptr));
107 nexttok(&ptr); // threads
108 nexttok(&ptr); // itrealvalue
109 nexttok(&ptr); // starttime
110 vss = strtoul(nexttok(&ptr), 0, 10); // vsize
111 rss = strtoul(nexttok(&ptr), 0, 10); // rss
112 nexttok(&ptr); // rlim
113 nexttok(&ptr); // startcode
114 nexttok(&ptr); // endcode
115 nexttok(&ptr); // startstack
116 nexttok(&ptr); // kstkesp
117 eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip
118 nexttok(&ptr); // signal
119 nexttok(&ptr); // blocked
120 nexttok(&ptr); // sigignore
121 nexttok(&ptr); // sigcatch
122 wchan = strtoul(nexttok(&ptr), 0, 10); // wchan
123 nexttok(&ptr); // nswap
124 nexttok(&ptr); // cnswap
125 nexttok(&ptr); // exit signal
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700126 psr = atoi(nexttok(&ptr)); // processor
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800127 rtprio = atoi(nexttok(&ptr)); // rt_priority
128 sched = atoi(nexttok(&ptr)); // scheduling policy
129
130 tty = atoi(nexttok(&ptr));
131
132 if(tid != 0) {
133 ppid = pid;
134 pid = tid;
135 }
136
137 pw = getpwuid(stats.st_uid);
138 if(pw == 0) {
139 sprintf(user,"%d",(int)stats.st_uid);
140 } else {
141 strcpy(user,pw->pw_name);
142 }
143
144 if(!namefilter || !strncmp(name, namefilter, strlen(namefilter))) {
San Mehat39274412009-10-27 11:53:22 -0700145 printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4);
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700146 if (display_flags & SHOW_CPU)
147 printf(" %-2d", psr);
148 if (display_flags & SHOW_PRIO)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800149 printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched);
San Mehat39274412009-10-27 11:53:22 -0700150 if (display_flags & SHOW_POLICY) {
151 SchedPolicy p;
152 if (get_sched_policy(pid, &p) < 0)
153 printf(" un ");
154 else {
155 if (p == SP_BACKGROUND)
156 printf(" bg ");
157 else if (p == SP_FOREGROUND)
158 printf(" fg ");
159 else
160 printf(" er ");
161 }
162 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800163 printf(" %08x %08x %s %s", wchan, eip, state, cmdline[0] ? cmdline : name);
164 if(display_flags&SHOW_TIME)
165 printf(" (u:%d, s:%d)", utime, stime);
San Mehat39274412009-10-27 11:53:22 -0700166
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800167 printf("\n");
168 }
169 return 0;
170}
171
172
173void ps_threads(int pid, char *namefilter)
174{
175 char tmp[128];
176 DIR *d;
177 struct dirent *de;
178
179 sprintf(tmp,"/proc/%d/task",pid);
180 d = opendir(tmp);
181 if(d == 0) return;
182
183 while((de = readdir(d)) != 0){
184 if(isdigit(de->d_name[0])){
185 int tid = atoi(de->d_name);
186 if(tid == pid) continue;
187 ps_line(pid, tid, namefilter);
188 }
189 }
190 closedir(d);
191}
192
193int ps_main(int argc, char **argv)
194{
195 DIR *d;
196 struct dirent *de;
197 char *namefilter = 0;
198 int pidfilter = 0;
199 int threads = 0;
200
201 d = opendir("/proc");
202 if(d == 0) return -1;
203
204 while(argc > 1){
205 if(!strcmp(argv[1],"-t")) {
206 threads = 1;
207 } else if(!strcmp(argv[1],"-x")) {
208 display_flags |= SHOW_TIME;
San Mehat39274412009-10-27 11:53:22 -0700209 } else if(!strcmp(argv[1],"-P")) {
210 display_flags |= SHOW_POLICY;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800211 } else if(!strcmp(argv[1],"-p")) {
212 display_flags |= SHOW_PRIO;
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700213 } else if(!strcmp(argv[1],"-c")) {
214 display_flags |= SHOW_CPU;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800215 } else if(isdigit(argv[1][0])){
216 pidfilter = atoi(argv[1]);
217 } else {
218 namefilter = argv[1];
219 }
220 argc--;
221 argv++;
222 }
223
Dmitry Shmidt8b37c912010-08-18 17:26:26 -0700224 printf("USER PID PPID VSIZE RSS %s%s %s WCHAN PC NAME\n",
225 (display_flags&SHOW_CPU)?"CPU ":"",
San Mehat39274412009-10-27 11:53:22 -0700226 (display_flags&SHOW_PRIO)?"PRIO NICE RTPRI SCHED ":"",
227 (display_flags&SHOW_POLICY)?"PCY " : "");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800228 while((de = readdir(d)) != 0){
229 if(isdigit(de->d_name[0])){
230 int pid = atoi(de->d_name);
231 if(!pidfilter || (pidfilter == pid)) {
232 ps_line(pid, 0, namefilter);
233 if(threads) ps_threads(pid, namefilter);
234 }
235 }
236 }
237 closedir(d);
238 return 0;
239}
240