source: MondoRescue/branches/3.3/mindi-busybox/procps/free.c@ 3837

Last change on this file since 3837 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 3.6 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * Mini free implementation for busybox
4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6 *
7 * Licensed under GPLv2, see file LICENSE in this source tree.
8 */
9
10/* getopt not needed */
11
12//usage:#define free_trivial_usage
13//usage: "" IF_DESKTOP("[-b/k/m/g]")
14//usage:#define free_full_usage "\n\n"
15//usage: "Display the amount of free and used system memory"
16//usage:
17//usage:#define free_example_usage
18//usage: "$ free\n"
19//usage: " total used free shared buffers\n"
20//usage: " Mem: 257628 248724 8904 59644 93124\n"
21//usage: " Swap: 128516 8404 120112\n"
22//usage: "Total: 386144 257128 129016\n"
23
24#include "libbb.h"
25#include "common_bufsiz.h"
26#ifdef __linux__
27# include <sys/sysinfo.h>
28#endif
29
30struct globals {
31 unsigned mem_unit;
32#if ENABLE_DESKTOP
33 unsigned unit_steps;
34# define G_unit_steps G.unit_steps
35#else
36# define G_unit_steps 10
37#endif
38} FIX_ALIASING;
39#define G (*(struct globals*)bb_common_bufsiz1)
40#define INIT_G() do { setup_common_bufsiz(); } while (0)
41
42
43static unsigned long long scale(unsigned long d)
44{
45 return ((unsigned long long)d * G.mem_unit) >> G_unit_steps;
46}
47
48static unsigned long parse_cached_kb(void)
49{
50 char buf[60]; /* actual lines we expect are ~30 chars or less */
51 FILE *fp;
52 unsigned long cached = 0;
53
54 fp = xfopen_for_read("/proc/meminfo");
55 while (fgets(buf, sizeof(buf), fp) != NULL) {
56 if (sscanf(buf, "Cached: %lu %*s\n", &cached) == 1)
57 break;
58 }
59 if (ENABLE_FEATURE_CLEAN_UP)
60 fclose(fp);
61
62 return cached;
63}
64
65int free_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
66int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
67{
68 struct sysinfo info;
69 unsigned long long cached;
70
71 INIT_G();
72
73#if ENABLE_DESKTOP
74 G.unit_steps = 10;
75 if (argv[1] && argv[1][0] == '-') {
76 switch (argv[1][1]) {
77 case 'b':
78 G.unit_steps = 0;
79 break;
80 case 'k': /* 2^10 */
81 /* G.unit_steps = 10; - already is */
82 break;
83 case 'm': /* 2^(2*10) */
84 G.unit_steps = 20;
85 break;
86 case 'g': /* 2^(3*10) */
87 G.unit_steps = 30;
88 break;
89 default:
90 bb_show_usage();
91 }
92 }
93#endif
94 printf(" %11s%11s%11s%11s%11s%11s\n"
95 "Mem: ",
96 "total",
97 "used",
98 "free",
99 "shared", "buffers", "cached" /* swap and total don't have these columns */
100 );
101
102 sysinfo(&info);
103 /* Kernels prior to 2.4.x will return info.mem_unit==0, so cope... */
104 G.mem_unit = (info.mem_unit ? info.mem_unit : 1);
105 /* Extract cached from /proc/meminfo and convert to mem_units */
106 cached = ((unsigned long long) parse_cached_kb() * 1024) / G.mem_unit;
107
108#define FIELDS_6 "%11llu%11llu%11llu%11llu%11llu%11llu\n"
109#define FIELDS_3 (FIELDS_6 + 3*6)
110#define FIELDS_2 (FIELDS_6 + 4*6)
111
112 printf(FIELDS_6,
113 scale(info.totalram), //total
114 scale(info.totalram - info.freeram), //used
115 scale(info.freeram), //free
116 scale(info.sharedram), //shared
117 scale(info.bufferram), //buffers
118 scale(cached) //cached
119 );
120 /* Show alternate, more meaningful busy/free numbers by counting
121 * buffer cache as free memory. */
122 printf("-/+ buffers/cache:");
123 cached += info.freeram;
124 cached += info.bufferram;
125 printf(FIELDS_2,
126 scale(info.totalram - cached), //used
127 scale(cached) //free
128 );
129#if BB_MMU
130 printf("Swap: ");
131 printf(FIELDS_3,
132 scale(info.totalswap), //total
133 scale(info.totalswap - info.freeswap), //used
134 scale(info.freeswap) //free
135 );
136#endif
137 return EXIT_SUCCESS;
138}
Note: See TracBrowser for help on using the repository browser.