procrank.c revision b56034796a7cadee89c4cd5e3c0f0730193231de
1e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/* 2e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * 4e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * you may not use this file except in compliance with the License. 6e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * You may obtain a copy of the License at 7e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * 8e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * 10e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * See the License for the specific language governing permissions and 14e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * limitations under the License. 15e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project */ 16e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 17e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <dirent.h> 18e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <errno.h> 19e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdlib.h> 20e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/types.h> 21e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <unistd.h> 22b56034796a7cadee89c4cd5e3c0f0730193231deOlivier Bailly#include <string.h> 23e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 24e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <pagemap/pagemap.h> 25e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 26e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstruct proc_info { 27e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pid_t pid; 28e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_memusage_t usage; 29e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project unsigned long wss; 30e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}; 31e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 32e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic void usage(char *myname); 3316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Rootstatic int getprocname(pid_t pid, char *buf, int len); 34e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int numcmp(long long a, long long b); 35e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 36e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define declare_sort(field) \ 37e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project static int sort_by_ ## field (const void *a, const void *b) 38e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 39e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectdeclare_sort(vss); 40e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectdeclare_sort(rss); 41e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectdeclare_sort(pss); 42e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectdeclare_sort(uss); 43e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 44e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint (*compfn)(const void *a, const void *b); 45e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int order; 46e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 47e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint main(int argc, char *argv[]) { 48e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_kernel_t *ker; 49e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_process_t *proc; 50e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pid_t *pids; 5116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root struct proc_info **procs; 52e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project size_t num_procs; 5316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root char cmdline[256]; // this must be within the range of int 54e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project int error; 55e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 56e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project #define WS_OFF 0 57e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project #define WS_ONLY 1 58e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project #define WS_RESET 2 59e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project int ws; 60e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 6116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root int arg; 6216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root size_t i, j; 63e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 64e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project compfn = &sort_by_pss; 65e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project order = -1; 66e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project ws = WS_OFF; 67e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 6816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root for (arg = 1; arg < argc; arg++) { 6916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (!strcmp(argv[arg], "-v")) { compfn = &sort_by_vss; continue; } 7016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (!strcmp(argv[arg], "-r")) { compfn = &sort_by_rss; continue; } 7116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (!strcmp(argv[arg], "-p")) { compfn = &sort_by_pss; continue; } 7216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (!strcmp(argv[arg], "-u")) { compfn = &sort_by_uss; continue; } 7316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (!strcmp(argv[arg], "-w")) { ws = WS_ONLY; continue; } 7416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (!strcmp(argv[arg], "-W")) { ws = WS_RESET; continue; } 7516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (!strcmp(argv[arg], "-R")) { order *= -1; continue; } 7616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (!strcmp(argv[arg], "-h")) { usage(argv[0]); exit(0); } 7716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root fprintf(stderr, "Invalid argument \"%s\".\n", argv[arg]); 78e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project usage(argv[0]); 79e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 80e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 81e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 82e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project error = pm_kernel_create(&ker); 83e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (error) { 84e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Error creating kernel interface -- " 85e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project "does this kernel have pagemap?\n"); 86e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 87e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 88e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 89e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project error = pm_kernel_pids(ker, &pids, &num_procs); 90e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (error) { 91e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Error listing processes.\n"); 92e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 93e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 94e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 9516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root procs = calloc(num_procs, sizeof(struct proc_info*)); 9616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (procs == NULL) { 9716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root fprintf(stderr, "calloc: %s", strerror(errno)); 9816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root exit(EXIT_FAILURE); 9916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 10016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 101e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project for (i = 0; i < num_procs; i++) { 102e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i] = malloc(sizeof(struct proc_info)); 10316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (procs[i] == NULL) { 104e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "malloc: %s\n", strerror(errno)); 105e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project exit(EXIT_FAILURE); 106e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 107e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->pid = pids[i]; 108e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project error = pm_process_create(ker, pids[i], &proc); 109e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (!error) { 110e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project switch (ws) { 111e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project case WS_OFF: 112e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_process_usage(proc, &procs[i]->usage); 113e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project break; 114e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project case WS_ONLY: 115e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_process_workingset(proc, &procs[i]->usage, 0); 116e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project break; 117e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project case WS_RESET: 118e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_process_workingset(proc, NULL, 1); 119e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project break; 120e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 121e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_process_destroy(proc); 122e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } else { 123e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "warning: could not create process interface for %d\n", pids[i]); 124e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project pm_memusage_zero(&procs[i]->usage); 125e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 126e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 127e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 128e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project free(pids); 129e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 130e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (ws == WS_RESET) exit(0); 131e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 132e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project j = 0; 133e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project for (i = 0; i < num_procs; i++) { 13416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (procs[i]->usage.vss) { 135e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[j++] = procs[i]; 13616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } else { 13716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root free(procs[i]); 13816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 139e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 140e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project num_procs = j; 141e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 142e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project qsort(procs, num_procs, sizeof(procs[0]), compfn); 143e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 144e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (ws) 145e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project printf("%5s %7s %7s %7s %s\n", "PID", "WRss", "WPss", "WUss", "cmdline"); 146e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project else 147e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project printf("%5s %7s %7s %7s %7s %s\n", "PID", "Vss", "Rss", "Pss", "Uss", "cmdline"); 14816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 149e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project for (i = 0; i < num_procs; i++) { 15016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (getprocname(procs[i]->pid, cmdline, (int)sizeof(cmdline)) < 0) { 15116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root /* 15216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * Something is probably seriously wrong if writing to the stack 15316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * failed. 15416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root */ 15516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root free(procs[i]); 15616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root continue; 15716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 15816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 159e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (ws) 160e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project printf("%5d %6dK %6dK %6dK %s\n", 161e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->pid, 162e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.rss / 1024, 163e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.pss / 1024, 164e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.uss / 1024, 165e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project cmdline 166e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project ); 167e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project else 168e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project printf("%5d %6dK %6dK %6dK %6dK %s\n", 169e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->pid, 170e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.vss / 1024, 171e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.rss / 1024, 172e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.pss / 1024, 173e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.uss / 1024, 174e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project cmdline 175e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project ); 17616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 17716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root free(procs[i]); 178e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 179e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 18016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root free(procs); 181e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 0; 182e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 183e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 184e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic void usage(char *myname) { 185e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Usage: %s [ -W ] [ -v | -r | -p | -u | -h ]\n" 186e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -v Sort by VSS.\n" 187e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -r Sort by RSS.\n" 188e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -p Sort by PSS.\n" 189e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -u Sort by USS.\n" 190e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " (Default sort order is PSS.)\n" 191e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -R Reverse sort order (default is descending).\n" 192e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -w Display statistics for working set only.\n" 193e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -W Reset working set of all processes.\n" 194e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -h Display this help screen.\n", 195e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project myname); 196e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 197e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 19816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root/* 19916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * Get the process name for a given PID. Inserts the process name into buffer 20016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * buf of length len. The size of the buffer must be greater than zero to get 20116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * any useful output. 20216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * 20316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * Note that fgets(3) only declares length as an int, so our buffer size is 20416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * also declared as an int. 20516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * 20616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * Returns 0 on success, a positive value on partial success, and -1 on 20716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * failure. Other interesting values: 20816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * 1 on failure to create string to examine proc cmdline entry 20916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * 2 on failure to open proc cmdline entry 21016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * 3 on failure to read proc cmdline entry 21116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root */ 21216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Rootstatic int getprocname(pid_t pid, char *buf, int len) { 21316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root char *filename; 214e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project FILE *f; 21516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root int rc = 0; 21616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root static const char* unknown_cmdline = "<unknown>"; 21716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 21816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (len <= 0) { 21916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root return -1; 22016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 22116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 22216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (asprintf(&filename, "/proc/%zd/cmdline", pid) < 0) { 22316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root rc = 1; 22416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root goto exit; 22516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 226e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 227e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project f = fopen(filename, "r"); 22816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (f == NULL) { 22916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root rc = 2; 23016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root goto releasefilename; 23116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 23216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 23316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (fgets(buf, len, f) == NULL) { 23416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root rc = 3; 23516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root goto closefile; 23616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 23716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 23816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Rootclosefile: 23916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root (void) fclose(f); 24016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Rootreleasefilename: 24116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root free(filename); 24216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Rootexit: 24316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (rc != 0) { 24416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root /* 24516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * The process went away before we could read its process name. Try 24616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * to give the user "<unknown>" here, but otherwise they get to look 24716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * at a blank. 24816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root */ 24916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (strlcpy(buf, unknown_cmdline, (size_t)len) >= (size_t)len) { 25016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root rc = 4; 25116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 25216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 25316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 25416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root return rc; 255e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 256e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 257e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int numcmp(long long a, long long b) { 258e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (a < b) return -1; 259e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (a > b) return 1; 260e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 0; 261e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 262e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 263e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define create_sort(field, compfn) \ 264e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project static int sort_by_ ## field (const void *a, const void *b) { \ 265e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return order * compfn( \ 266e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project (*((struct proc_info**)a))->usage.field, \ 267e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project (*((struct proc_info**)b))->usage.field \ 268e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project ); \ 269e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 270e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 271e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectcreate_sort(vss, numcmp) 272e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectcreate_sort(rss, numcmp) 273e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectcreate_sort(pss, numcmp) 274e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectcreate_sort(uss, numcmp) 275