diff options
Diffstat (limited to 'procps/pmap.c')
-rw-r--r-- | procps/pmap.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/procps/pmap.c b/procps/pmap.c new file mode 100644 index 0000000..cfa94ed --- /dev/null +++ b/procps/pmap.c @@ -0,0 +1,111 @@ +/* + * pmap implementation for busybox + * + * Copyright (C) 2010 Nokia Corporation. All rights reserved. + * Written by Alexander Shishkin <virtuoso@slind.org> + * + * Licensed under GPLv2 or later, see the LICENSE file in this source tree + * for details. + */ + +//applet:IF_PMAP(APPLET(pmap, _BB_DIR_USR_BIN, _BB_SUID_DROP)) +//kbuild:lib-$(CONFIG_PMAP) += pmap.o + +//config:config PMAP +//config: bool "pmap" +//config: default y +//config: help +//config: Display processes' memory mappings. + +//usage:#define pmap_trivial_usage +//usage: "[-x][-q] PID" +//usage:#define pmap_full_usage "\n\n" +//usage: "Display detailed precesses' memory usage\n" +//usage: "\nOptions:" +//usage: "\n -x show details" +//usage: "\n -q quiet" + +#include "libbb.h" + +#if ULONG_MAX == 0xffffffff +# define TABS "\t" +# define AFMT "8" +# define DASHES "" +#else +# define TABS "\t\t" +# define AFMT "16" +# define DASHES "--------" +#endif + +enum { + OPT_x = 1 << 0, + OPT_q = 1 << 1, +}; + +static void print_smaprec(struct smaprec *currec, void *data) +{ + unsigned opt = (unsigned)data; + + printf("%0" AFMT "lx ", currec->smap_start); + + if (opt & OPT_x) + printf("%7lu %7lu %7lu %7lu ", + currec->smap_size, + currec->smap_pss, + currec->private_dirty, + currec->smap_swap); + else + printf("%7luK", currec->smap_size); + + printf(" %.4s %s\n", currec->smap_mode, currec->smap_name); +} + +static int procps_get_maps(pid_t pid, unsigned opt) +{ + struct smaprec total; + int ret; + char buf[256]; + + read_cmdline(buf, sizeof(buf), pid, "no such process"); + printf("%u: %s\n", (int)pid, buf); + + if (!(opt & OPT_q) && (opt & OPT_x)) + puts("Address" TABS " Kbytes PSS Dirty Swap Mode Mapping"); + + memset(&total, 0, sizeof(total)); + + ret = procps_read_smaps(pid, &total, print_smaprec, (void*)opt); + if (ret) + return ret; + + if (!(opt & OPT_q)) { + if (opt & OPT_x) + printf("--------" DASHES " ------ ------ ------ ------\n" + "total" TABS " %7lu %7lu %7lu %7lu\n", + total.smap_size, total.smap_pss, total.private_dirty, total.smap_swap); + else + printf("mapped: %luK\n", total.smap_size); + } + + return 0; +} + +int pmap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int pmap_main(int argc UNUSED_PARAM, char **argv) +{ + unsigned opts; + int ret; + + opts = getopt32(argv, "xq"); + argv += optind; + + ret = 0; + while (*argv) { + pid_t pid = xatoi_positive(*argv++); + /* GNU pmap returns 42 if any of the pids failed */ + if (procps_get_maps(pid, opts) != 0) + ret = 42; + } + + return ret; +} |