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