/toolbox/ps.c

https://gitlab.com/infraredbg/android_system_core-mt6589 · C · 301 lines · 270 code · 31 blank · 0 comment · 70 complexity · adc93881dd878d860e5ecbd1847e31dc MD5 · raw file

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