procrank.c revision eff788820689e7c2bfd456934e8132a381b31235
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]; 108eff788820689e7c2bfd456934e8132a381b31235Colin Cross pm_memusage_zero(&procs[i]->usage); 109e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project error = pm_process_create(ker, pids[i], &proc); 110eff788820689e7c2bfd456934e8132a381b31235Colin Cross if (error) { 111e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "warning: could not create process interface for %d\n", pids[i]); 112eff788820689e7c2bfd456934e8132a381b31235Colin Cross continue; 113eff788820689e7c2bfd456934e8132a381b31235Colin Cross } 114eff788820689e7c2bfd456934e8132a381b31235Colin Cross 115eff788820689e7c2bfd456934e8132a381b31235Colin Cross switch (ws) { 116eff788820689e7c2bfd456934e8132a381b31235Colin Cross case WS_OFF: 117eff788820689e7c2bfd456934e8132a381b31235Colin Cross error = pm_process_usage(proc, &procs[i]->usage); 118eff788820689e7c2bfd456934e8132a381b31235Colin Cross break; 119eff788820689e7c2bfd456934e8132a381b31235Colin Cross case WS_ONLY: 120eff788820689e7c2bfd456934e8132a381b31235Colin Cross error = pm_process_workingset(proc, &procs[i]->usage, 0); 121eff788820689e7c2bfd456934e8132a381b31235Colin Cross break; 122eff788820689e7c2bfd456934e8132a381b31235Colin Cross case WS_RESET: 123eff788820689e7c2bfd456934e8132a381b31235Colin Cross error = pm_process_workingset(proc, NULL, 1); 124eff788820689e7c2bfd456934e8132a381b31235Colin Cross break; 125e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 126eff788820689e7c2bfd456934e8132a381b31235Colin Cross 127eff788820689e7c2bfd456934e8132a381b31235Colin Cross if (error) { 128eff788820689e7c2bfd456934e8132a381b31235Colin Cross fprintf(stderr, "warning: could not read usage for %d\n", pids[i]); 129eff788820689e7c2bfd456934e8132a381b31235Colin Cross } 130eff788820689e7c2bfd456934e8132a381b31235Colin Cross 131eff788820689e7c2bfd456934e8132a381b31235Colin Cross pm_process_destroy(proc); 132e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 133e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 134e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project free(pids); 135e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 136e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (ws == WS_RESET) exit(0); 137e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 138e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project j = 0; 139e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project for (i = 0; i < num_procs; i++) { 14016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (procs[i]->usage.vss) { 141e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[j++] = procs[i]; 14216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } else { 14316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root free(procs[i]); 14416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 145e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 146e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project num_procs = j; 147e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 148e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project qsort(procs, num_procs, sizeof(procs[0]), compfn); 149e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 150e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (ws) 151e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project printf("%5s %7s %7s %7s %s\n", "PID", "WRss", "WPss", "WUss", "cmdline"); 152e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project else 153e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project printf("%5s %7s %7s %7s %7s %s\n", "PID", "Vss", "Rss", "Pss", "Uss", "cmdline"); 15416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 155e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project for (i = 0; i < num_procs; i++) { 15616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (getprocname(procs[i]->pid, cmdline, (int)sizeof(cmdline)) < 0) { 15716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root /* 15816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * Something is probably seriously wrong if writing to the stack 15916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * failed. 16016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root */ 16116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root free(procs[i]); 16216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root continue; 16316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 16416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 165e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (ws) 166e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project printf("%5d %6dK %6dK %6dK %s\n", 167e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->pid, 168e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.rss / 1024, 169e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.pss / 1024, 170e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.uss / 1024, 171e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project cmdline 172e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project ); 173e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project else 174e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project printf("%5d %6dK %6dK %6dK %6dK %s\n", 175e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->pid, 176e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.vss / 1024, 177e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.rss / 1024, 178e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.pss / 1024, 179e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project procs[i]->usage.uss / 1024, 180e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project cmdline 181e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project ); 18216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 18316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root free(procs[i]); 184e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 185e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 18616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root free(procs); 187e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 0; 188e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 189e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 190e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic void usage(char *myname) { 191e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project fprintf(stderr, "Usage: %s [ -W ] [ -v | -r | -p | -u | -h ]\n" 192e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -v Sort by VSS.\n" 193e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -r Sort by RSS.\n" 194e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -p Sort by PSS.\n" 195e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -u Sort by USS.\n" 196e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " (Default sort order is PSS.)\n" 197e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -R Reverse sort order (default is descending).\n" 198e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -w Display statistics for working set only.\n" 199e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -W Reset working set of all processes.\n" 200e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project " -h Display this help screen.\n", 201e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project myname); 202e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 203e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 20416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root/* 20516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * Get the process name for a given PID. Inserts the process name into buffer 20616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * buf of length len. The size of the buffer must be greater than zero to get 20716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * any useful output. 20816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * 20916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * Note that fgets(3) only declares length as an int, so our buffer size is 21016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * also declared as an int. 21116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * 21216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * Returns 0 on success, a positive value on partial success, and -1 on 21316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * failure. Other interesting values: 21416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * 1 on failure to create string to examine proc cmdline entry 21516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * 2 on failure to open proc cmdline entry 21616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * 3 on failure to read proc cmdline entry 21716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root */ 21816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Rootstatic int getprocname(pid_t pid, char *buf, int len) { 21916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root char *filename; 220e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project FILE *f; 22116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root int rc = 0; 22216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root static const char* unknown_cmdline = "<unknown>"; 22316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 22416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (len <= 0) { 22516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root return -1; 22616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 22716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 22816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (asprintf(&filename, "/proc/%zd/cmdline", pid) < 0) { 22916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root rc = 1; 23016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root goto exit; 23116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 232e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 233e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project f = fopen(filename, "r"); 23416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (f == NULL) { 23516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root rc = 2; 23616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root goto releasefilename; 23716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 23816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 23916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (fgets(buf, len, f) == NULL) { 24016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root rc = 3; 24116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root goto closefile; 24216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 24316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 24416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Rootclosefile: 24516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root (void) fclose(f); 24616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Rootreleasefilename: 24716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root free(filename); 24816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Rootexit: 24916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (rc != 0) { 25016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root /* 25116abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * The process went away before we could read its process name. Try 25216abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * to give the user "<unknown>" here, but otherwise they get to look 25316abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root * at a blank. 25416abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root */ 25516abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root if (strlcpy(buf, unknown_cmdline, (size_t)len) >= (size_t)len) { 25616abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root rc = 4; 25716abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 25816abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root } 25916abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root 26016abe7acb8f1dbeb8b9b1dc41061a53dcbfea851Kenny Root return rc; 261e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 262e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 263e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int numcmp(long long a, long long b) { 264e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (a < b) return -1; 265e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project if (a > b) return 1; 266e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return 0; 267e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project} 268e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 269e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define create_sort(field, compfn) \ 270e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project static int sort_by_ ## field (const void *a, const void *b) { \ 271e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project return order * compfn( \ 272e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project (*((struct proc_info**)a))->usage.field, \ 273e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project (*((struct proc_info**)b))->usage.field \ 274e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project ); \ 275e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project } 276e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project 277e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectcreate_sort(vss, numcmp) 278e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectcreate_sort(rss, numcmp) 279e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectcreate_sort(pss, numcmp) 280e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectcreate_sort(uss, numcmp) 281