Bump to version 1.22.1
[platform/upstream/busybox.git] / procps / pmap.c
1 /*
2  * pmap implementation for busybox
3  *
4  * Copyright (C) 2010 Nokia Corporation. All rights reserved.
5  * Written by Alexander Shishkin <virtuoso@slind.org>
6  *
7  * Licensed under GPLv2 or later, see the LICENSE file in this source tree
8  * for details.
9  */
10
11 //config:config PMAP
12 //config:       bool "pmap"
13 //config:       default y
14 //config:       help
15 //config:         Display processes' memory mappings.
16
17 //applet:IF_PMAP(APPLET(pmap, BB_DIR_USR_BIN, BB_SUID_DROP))
18 //kbuild:lib-$(CONFIG_PMAP) += pmap.o
19
20 //usage:#define pmap_trivial_usage
21 //usage:       "[-xq] PID"
22 //usage:#define pmap_full_usage "\n\n"
23 //usage:       "Display detailed process memory usage"
24 //usage:     "\n"
25 //usage:     "\n        -x      Show details"
26 //usage:     "\n        -q      Quiet"
27
28 #include "libbb.h"
29
30 #if ULONG_MAX == 0xffffffff
31 # define TABS "\t"
32 # define AFMT "8"
33 # define DASHES ""
34 #else
35 # define TABS "\t\t"
36 # define AFMT "16"
37 # define DASHES "--------"
38 #endif
39
40 enum {
41         OPT_x = 1 << 0,
42         OPT_q = 1 << 1,
43 };
44
45 static void print_smaprec(struct smaprec *currec, void *data)
46 {
47         unsigned opt = (uintptr_t)data;
48
49         printf("%0" AFMT "lx ", currec->smap_start);
50
51         if (opt & OPT_x)
52                 printf("%7lu %7lu %7lu %7lu ",
53                         currec->smap_size,
54                         currec->smap_pss,
55                         currec->private_dirty,
56                         currec->smap_swap);
57         else
58                 printf("%7luK", currec->smap_size);
59
60         printf(" %.4s  %s\n", currec->smap_mode, currec->smap_name);
61 }
62
63 static int procps_get_maps(pid_t pid, unsigned opt)
64 {
65         struct smaprec total;
66         int ret;
67         char buf[256];
68
69         read_cmdline(buf, sizeof(buf), pid, "no such process");
70         printf("%u: %s\n", (int)pid, buf);
71
72         if (!(opt & OPT_q) && (opt & OPT_x))
73                 puts("Address" TABS "  Kbytes     PSS   Dirty    Swap  Mode  Mapping");
74
75         memset(&total, 0, sizeof(total));
76
77         ret = procps_read_smaps(pid, &total, print_smaprec, (void*)(uintptr_t)opt);
78         if (ret)
79                 return ret;
80
81         if (!(opt & OPT_q)) {
82                 if (opt & OPT_x)
83                         printf("--------" DASHES "  ------  ------  ------  ------\n"
84                                 "total" TABS " %7lu %7lu %7lu %7lu\n",
85                                 total.smap_size, total.smap_pss, total.private_dirty, total.smap_swap);
86                 else
87                         printf("mapped: %luK\n", total.smap_size);
88         }
89
90         return 0;
91 }
92
93 int pmap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
94 int pmap_main(int argc UNUSED_PARAM, char **argv)
95 {
96         unsigned opts;
97         int ret;
98
99         opts = getopt32(argv, "xq");
100         argv += optind;
101
102         ret = 0;
103         while (*argv) {
104                 pid_t pid = xatoi_positive(*argv++);
105                 /* GNU pmap returns 42 if any of the pids failed */
106                 if (procps_get_maps(pid, opts) != 0)
107                         ret = 42;
108         }
109
110         return ret;
111 }