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 17 static char *nexttoksep(char **strp, char *sep) 18 { 19 char *p = strsep(strp,sep); 20 return (p == 0) ? "" : p; 21 } 22 static 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 #define SHOW_CPU 8 31 32 static int display_flags = 0; 33 34 static 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; 45 int prio, nice, rtprio, sched, psr; 46 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 126 psr = atoi(nexttok(&ptr)); // processor 127 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))) { 145 printf("%-9s %-5d %-5d %-6d %-5d", user, pid, ppid, vss / 1024, rss * 4); 146 if (display_flags & SHOW_CPU) 147 printf(" %-2d", psr); 148 if (display_flags & SHOW_PRIO) 149 printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched); 150 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 } 163 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); 166 167 printf("\n"); 168 } 169 return 0; 170 } 171 172 173 void 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 193 int 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; 209 } else if(!strcmp(argv[1],"-P")) { 210 display_flags |= SHOW_POLICY; 211 } else if(!strcmp(argv[1],"-p")) { 212 display_flags |= SHOW_PRIO; 213 } else if(!strcmp(argv[1],"-c")) { 214 display_flags |= SHOW_CPU; 215 } else if(isdigit(argv[1][0])){ 216 pidfilter = atoi(argv[1]); 217 } else { 218 namefilter = argv[1]; 219 } 220 argc--; 221 argv++; 222 } 223 224 printf("USER PID PPID VSIZE RSS %s%s %s WCHAN PC NAME\n", 225 (display_flags&SHOW_CPU)?"CPU ":"", 226 (display_flags&SHOW_PRIO)?"PRIO NICE RTPRI SCHED ":"", 227 (display_flags&SHOW_POLICY)?"PCY " : ""); 228 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 241