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