1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h>
20badbd6565fea17be39d82eba858fa76d28920a4Elliott Hughes#include <dirent.h>
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h>
48ac94d3a545c65499b6492ec2c76d4757535fcfeElliott Hughes#include <inttypes.h>
50badbd6565fea17be39d82eba858fa76d28920a4Elliott Hughes#include <pwd.h>
60badbd6565fea17be39d82eba858fa76d28920a4Elliott Hughes#include <stdio.h>
70badbd6565fea17be39d82eba858fa76d28920a4Elliott Hughes#include <stdlib.h>
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h>
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h>
110badbd6565fea17be39d82eba858fa76d28920a4Elliott Hughes#include <unistd.h>
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
13392744175c4de67dc98e72da6745e6351118c985San Mehat#include <cutils/sched_policy.h>
14392744175c4de67dc98e72da6745e6351118c985San Mehat
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char *nexttoksep(char **strp, char *sep)
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *p = strsep(strp,sep);
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return (p == 0) ? "" : p;
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char *nexttok(char **strp)
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return nexttoksep(strp, " ");
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define SHOW_PRIO 1
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define SHOW_TIME 2
27392744175c4de67dc98e72da6745e6351118c985San Mehat#define SHOW_POLICY 4
288b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt#define SHOW_CPU  8
298290d1083ec7eee3f32265012f5d6be2774c4afcStephen Smalley#define SHOW_MACLABEL 16
30377cb2ab3aff08119c5934ff0e582cb604884f8eMarco Nelissen#define SHOW_NUMERIC_UID 32
317c01585339ef8ccbfb33e9886689e4018ae58978Kenny Root#define SHOW_ABI 64
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3308b3466bc27d00af535711674f3273b04c7e15a5Chris Dearman#if __LP64__
3408b3466bc27d00af535711674f3273b04c7e15a5Chris Dearman#define PC_WIDTH 10 /* Realistically, the top bits will be 0, so don't waste space. */
3508b3466bc27d00af535711674f3273b04c7e15a5Chris Dearman#else
3608b3466bc27d00af535711674f3273b04c7e15a5Chris Dearman#define PC_WIDTH (2*sizeof(uintptr_t))
3708b3466bc27d00af535711674f3273b04c7e15a5Chris Dearman#endif
3808b3466bc27d00af535711674f3273b04c7e15a5Chris Dearman
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int display_flags = 0;
40b5fc3132eee1c3a783c566440d9132f792d10ec4Elliott Hughesstatic int ppid_filter = 0;
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
428f197e65790265b362fc01c5f730365dc7dc1809Kenny Rootstatic void print_exe_abi(int pid);
438f197e65790265b362fc01c5f730365dc7dc1809Kenny Root
445dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughesstatic int ps_line(int pid, int tid)
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char statline[1024];
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char cmdline[1024];
488290d1083ec7eee3f32265012f5d6be2774c4afcStephen Smalley    char macline[1024];
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char user[32];
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct stat stats;
515dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    int r;
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char *ptr, *name, *state;
53aa907768af7ba9e29901d356cdcac6a436970323Mark Salyzyn    int ppid;
5408b3466bc27d00af535711674f3273b04c7e15a5Chris Dearman    unsigned rss, vss;
5508b3466bc27d00af535711674f3273b04c7e15a5Chris Dearman    uintptr_t eip;
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned utime, stime;
578b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt    int prio, nice, rtprio, sched, psr;
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct passwd *pw;
59377cb2ab3aff08119c5934ff0e582cb604884f8eMarco Nelissen
606268d4c057d33ae0aa6a65c7d7f01a4830581868Phani (Gargey) Avadhanam    sprintf(statline, "/proc/%d", tid ? tid : pid);
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    stat(statline, &stats);
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(tid) {
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sprintf(statline, "/proc/%d/task/%d/stat", pid, tid);
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cmdline[0] = 0;
668290d1083ec7eee3f32265012f5d6be2774c4afcStephen Smalley        snprintf(macline, sizeof(macline), "/proc/%d/task/%d/attr/current", pid, tid);
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sprintf(statline, "/proc/%d/stat", pid);
698290d1083ec7eee3f32265012f5d6be2774c4afcStephen Smalley        sprintf(cmdline, "/proc/%d/cmdline", pid);
708290d1083ec7eee3f32265012f5d6be2774c4afcStephen Smalley        snprintf(macline, sizeof(macline), "/proc/%d/attr/current", pid);
715dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes        int fd = open(cmdline, O_RDONLY);
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(fd == 0) {
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            r = 0;
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            r = read(fd, cmdline, 1023);
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            close(fd);
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(r < 0) r = 0;
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        cmdline[r] = 0;
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
81377cb2ab3aff08119c5934ff0e582cb604884f8eMarco Nelissen
825dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    int fd = open(statline, O_RDONLY);
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd == 0) return -1;
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    r = read(fd, statline, 1023);
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    close(fd);
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(r < 0) return -1;
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    statline[r] = 0;
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ptr = statline;
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // skip pid
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ptr++;          // skip "("
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    name = ptr;
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')',
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *ptr++ = '\0';           // and null-terminate name.
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ptr++;          // skip " "
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    state = nexttok(&ptr);
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ppid = atoi(nexttok(&ptr));
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // pgrp
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // sid
102aa907768af7ba9e29901d356cdcac6a436970323Mark Salyzyn    nexttok(&ptr); // tty
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // tpgid
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // flags
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // minflt
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // cminflt
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // majflt
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // cmajflt
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 1
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    utime = atoi(nexttok(&ptr));
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    stime = atoi(nexttok(&ptr));
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // utime
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // stime
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // cutime
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // cstime
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    prio = atoi(nexttok(&ptr));
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nice = atoi(nexttok(&ptr));
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // threads
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // itrealvalue
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // starttime
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    vss = strtoul(nexttok(&ptr), 0, 10); // vsize
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    rss = strtoul(nexttok(&ptr), 0, 10); // rss
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // rlim
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // startcode
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // endcode
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // startstack
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // kstkesp
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // signal
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // blocked
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // sigignore
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // sigcatch
13508b3466bc27d00af535711674f3273b04c7e15a5Chris Dearman    nexttok(&ptr); // wchan
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // nswap
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // cnswap
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    nexttok(&ptr); // exit signal
1398b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt    psr = atoi(nexttok(&ptr)); // processor
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    rtprio = atoi(nexttok(&ptr)); // rt_priority
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sched = atoi(nexttok(&ptr)); // scheduling policy
142377cb2ab3aff08119c5934ff0e582cb604884f8eMarco Nelissen
143aa907768af7ba9e29901d356cdcac6a436970323Mark Salyzyn    nexttok(&ptr); // tty
144377cb2ab3aff08119c5934ff0e582cb604884f8eMarco Nelissen
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(tid != 0) {
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ppid = pid;
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pid = tid;
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pw = getpwuid(stats.st_uid);
151377cb2ab3aff08119c5934ff0e582cb604884f8eMarco Nelissen    if(pw == 0 || (display_flags & SHOW_NUMERIC_UID)) {
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sprintf(user,"%d",(int)stats.st_uid);
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        strcpy(user,pw->pw_name);
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
156377cb2ab3aff08119c5934ff0e582cb604884f8eMarco Nelissen
157b5fc3132eee1c3a783c566440d9132f792d10ec4Elliott Hughes    if(ppid_filter != 0 && ppid != ppid_filter) {
158b5fc3132eee1c3a783c566440d9132f792d10ec4Elliott Hughes        return 0;
159b5fc3132eee1c3a783c566440d9132f792d10ec4Elliott Hughes    }
160b5fc3132eee1c3a783c566440d9132f792d10ec4Elliott Hughes
1615dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    if (display_flags & SHOW_MACLABEL) {
1625dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes        fd = open(macline, O_RDONLY);
1635dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes        strcpy(macline, "-");
1645dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes        if (fd >= 0) {
1655dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes            r = read(fd, macline, sizeof(macline)-1);
1665dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes            close(fd);
1675dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes            if (r > 0)
1685dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes                macline[r] = 0;
1698f197e65790265b362fc01c5f730365dc7dc1809Kenny Root        }
170d2e26c0e309dd43352d444e11191e7261621faf9Elliott Hughes        printf("%-30s ", macline);
1715dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    }
172392744175c4de67dc98e72da6745e6351118c985San Mehat
1735dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4);
1745dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    if (display_flags & SHOW_CPU)
1755dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes        printf(" %-2d", psr);
1765dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    if (display_flags & SHOW_PRIO)
1775dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes        printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched);
1785dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    if (display_flags & SHOW_POLICY) {
1795dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes        SchedPolicy p;
1805dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes        if (get_sched_policy(pid, &p) < 0)
1815dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes            printf(" un ");
1825dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes        else
1835dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes            printf(" %.2s ", get_sched_policy_name(p));
1845dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    }
1855dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    char path[PATH_MAX];
1865dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    snprintf(path, sizeof(path), "/proc/%d/wchan", pid);
1875dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    char wchan[10];
1885dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    fd = open(path, O_RDONLY);
1895dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    ssize_t wchan_len = read(fd, wchan, sizeof(wchan));
1905dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    if (wchan_len == -1) {
1915dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes        wchan[wchan_len = 0] = '\0';
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1935dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    close(fd);
1945dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    printf(" %10.*s %0*" PRIxPTR " %s ", (int) wchan_len, wchan, (int) PC_WIDTH, eip, state);
1955dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    if (display_flags & SHOW_ABI) {
1965dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes        print_exe_abi(pid);
1975dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    }
1985dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    printf("%s", cmdline[0] ? cmdline : name);
1995dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    if(display_flags&SHOW_TIME)
2005dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes        printf(" (u:%d, s:%d)", utime, stime);
2015dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes
2025dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes    printf("\n");
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
2068f197e65790265b362fc01c5f730365dc7dc1809Kenny Rootstatic void print_exe_abi(int pid)
2078f197e65790265b362fc01c5f730365dc7dc1809Kenny Root{
2088f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    int fd, r;
2098f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    char exeline[1024];
2108f197e65790265b362fc01c5f730365dc7dc1809Kenny Root
2118f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    sprintf(exeline, "/proc/%d/exe", pid);
2128f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    fd = open(exeline, O_RDONLY);
2138f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    if(fd == 0) {
2148f197e65790265b362fc01c5f730365dc7dc1809Kenny Root        printf("    ");
2158f197e65790265b362fc01c5f730365dc7dc1809Kenny Root        return;
2168f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    }
2178f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    r = read(fd, exeline, 5 /* 4 byte ELFMAG + 1 byte EI_CLASS */);
2188f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    close(fd);
2198f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    if(r < 0) {
2208f197e65790265b362fc01c5f730365dc7dc1809Kenny Root        printf("    ");
2218f197e65790265b362fc01c5f730365dc7dc1809Kenny Root        return;
2228f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    }
2238f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    if (memcmp("\177ELF", exeline, 4) != 0) {
2248f197e65790265b362fc01c5f730365dc7dc1809Kenny Root        printf("??  ");
2258f197e65790265b362fc01c5f730365dc7dc1809Kenny Root        return;
2268f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    }
2278f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    switch (exeline[4]) {
2288f197e65790265b362fc01c5f730365dc7dc1809Kenny Root        case 1:
2298f197e65790265b362fc01c5f730365dc7dc1809Kenny Root            printf("32  ");
2308f197e65790265b362fc01c5f730365dc7dc1809Kenny Root            return;
2318f197e65790265b362fc01c5f730365dc7dc1809Kenny Root        case 2:
2328f197e65790265b362fc01c5f730365dc7dc1809Kenny Root            printf("64  ");
2338f197e65790265b362fc01c5f730365dc7dc1809Kenny Root            return;
2348f197e65790265b362fc01c5f730365dc7dc1809Kenny Root        default:
2358f197e65790265b362fc01c5f730365dc7dc1809Kenny Root            printf("??  ");
2368f197e65790265b362fc01c5f730365dc7dc1809Kenny Root            return;
2378f197e65790265b362fc01c5f730365dc7dc1809Kenny Root    }
2388f197e65790265b362fc01c5f730365dc7dc1809Kenny Root}
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
2405dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughesvoid ps_threads(int pid)
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char tmp[128];
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DIR *d;
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct dirent *de;
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sprintf(tmp,"/proc/%d/task",pid);
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    d = opendir(tmp);
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(d == 0) return;
249377cb2ab3aff08119c5934ff0e582cb604884f8eMarco Nelissen
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while((de = readdir(d)) != 0){
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(isdigit(de->d_name[0])){
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int tid = atoi(de->d_name);
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(tid == pid) continue;
2545dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes            ps_line(pid, tid);
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
257377cb2ab3aff08119c5934ff0e582cb604884f8eMarco Nelissen    closedir(d);
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ps_main(int argc, char **argv)
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DIR *d;
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct dirent *de;
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int pidfilter = 0;
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int threads = 0;
266377cb2ab3aff08119c5934ff0e582cb604884f8eMarco Nelissen
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while(argc > 1){
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(!strcmp(argv[1],"-t")) {
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            threads = 1;
270377cb2ab3aff08119c5934ff0e582cb604884f8eMarco Nelissen        } else if(!strcmp(argv[1],"-n")) {
271377cb2ab3aff08119c5934ff0e582cb604884f8eMarco Nelissen            display_flags |= SHOW_NUMERIC_UID;
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if(!strcmp(argv[1],"-x")) {
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            display_flags |= SHOW_TIME;
2748290d1083ec7eee3f32265012f5d6be2774c4afcStephen Smalley        } else if(!strcmp(argv[1], "-Z")) {
2758290d1083ec7eee3f32265012f5d6be2774c4afcStephen Smalley            display_flags |= SHOW_MACLABEL;
276392744175c4de67dc98e72da6745e6351118c985San Mehat        } else if(!strcmp(argv[1],"-P")) {
277392744175c4de67dc98e72da6745e6351118c985San Mehat            display_flags |= SHOW_POLICY;
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else if(!strcmp(argv[1],"-p")) {
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            display_flags |= SHOW_PRIO;
2808b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt        } else if(!strcmp(argv[1],"-c")) {
2818b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt            display_flags |= SHOW_CPU;
2828f197e65790265b362fc01c5f730365dc7dc1809Kenny Root        } else if(!strcmp(argv[1],"--abi")) {
2838f197e65790265b362fc01c5f730365dc7dc1809Kenny Root            display_flags |= SHOW_ABI;
284b5fc3132eee1c3a783c566440d9132f792d10ec4Elliott Hughes        } else if(!strcmp(argv[1],"--ppid")) {
285b5fc3132eee1c3a783c566440d9132f792d10ec4Elliott Hughes            ppid_filter = atoi(argv[2]);
2865dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes            if (ppid_filter == 0) {
28778e08066f272c2adb41a1c80a7d566bd8b31d607Christopher Ferris                /* Bug 26554285: Use printf because some apps require at least
28878e08066f272c2adb41a1c80a7d566bd8b31d607Christopher Ferris                 * one line of output to stdout even for errors.
28978e08066f272c2adb41a1c80a7d566bd8b31d607Christopher Ferris                 */
29078e08066f272c2adb41a1c80a7d566bd8b31d607Christopher Ferris                printf("bad ppid '%s'\n", argv[2]);
2915dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes                return 1;
2925dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes            }
293b5fc3132eee1c3a783c566440d9132f792d10ec4Elliott Hughes            argc--;
294b5fc3132eee1c3a783c566440d9132f792d10ec4Elliott Hughes            argv++;
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
2965dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes            pidfilter = atoi(argv[1]);
2975dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes            if (pidfilter == 0) {
29878e08066f272c2adb41a1c80a7d566bd8b31d607Christopher Ferris                /* Bug 26554285: Use printf because some apps require at least
29978e08066f272c2adb41a1c80a7d566bd8b31d607Christopher Ferris                 * one line of output to stdout even for errors.
30078e08066f272c2adb41a1c80a7d566bd8b31d607Christopher Ferris                 */
30178e08066f272c2adb41a1c80a7d566bd8b31d607Christopher Ferris                printf("bad pid '%s'\n", argv[1]);
3025dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes                return 1;
3035dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes            }
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        argc--;
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        argv++;
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3098290d1083ec7eee3f32265012f5d6be2774c4afcStephen Smalley    if (display_flags & SHOW_MACLABEL) {
310d2e26c0e309dd43352d444e11191e7261621faf9Elliott Hughes        printf("LABEL                          ");
3118290d1083ec7eee3f32265012f5d6be2774c4afcStephen Smalley    }
312d2e26c0e309dd43352d444e11191e7261621faf9Elliott Hughes    printf("USER      PID   PPID  VSIZE  RSS  %s%s %sWCHAN      %*s  %sNAME\n",
313d2e26c0e309dd43352d444e11191e7261621faf9Elliott Hughes           (display_flags&SHOW_CPU)?"CPU ":"",
314d2e26c0e309dd43352d444e11191e7261621faf9Elliott Hughes           (display_flags&SHOW_PRIO)?"PRIO  NICE  RTPRI SCHED ":"",
315d2e26c0e309dd43352d444e11191e7261621faf9Elliott Hughes           (display_flags&SHOW_POLICY)?"PCY " : "",
316d2e26c0e309dd43352d444e11191e7261621faf9Elliott Hughes           (int) PC_WIDTH, "PC",
317d2e26c0e309dd43352d444e11191e7261621faf9Elliott Hughes           (display_flags&SHOW_ABI)?"ABI " : "");
318d2e26c0e309dd43352d444e11191e7261621faf9Elliott Hughes
31978e08066f272c2adb41a1c80a7d566bd8b31d607Christopher Ferris    d = opendir("/proc");
32078e08066f272c2adb41a1c80a7d566bd8b31d607Christopher Ferris    if(d == 0) return -1;
32178e08066f272c2adb41a1c80a7d566bd8b31d607Christopher Ferris
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while((de = readdir(d)) != 0){
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(isdigit(de->d_name[0])){
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int pid = atoi(de->d_name);
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if(!pidfilter || (pidfilter == pid)) {
3265dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes                ps_line(pid, 0);
3275dc119a67b87bd809564f0b18750c5d784c55201Elliott Hughes                if(threads) ps_threads(pid);
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    closedir(d);
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
335