OK, I pulled *mem_unit into the format macro to avoid the overflow; now the
memory values get shifted first, which will hopefully avoid the overflow.
---
include/usage.src.h | 8 +++++-
procps/free.c | 74 +++++++++++++++++++++++++++------------------------
2 files changed, 46 insertions(+), 36 deletions(-)
diff --git a/include/usage.src.h b/include/usage.src.h
index c26ed8b..f4b8ac7 100644
--- a/include/usage.src.h
+++ b/include/usage.src.h
@@ -1303,7 +1303,13 @@ INSERT
#define free_trivial_usage \
""
#define free_full_usage "\n\n" \
- "Display the amount of free and used system memory"
+ "Display the amount of free and used system memory" \
+ "\nOptions:" \
+ "\n -b show output in bytes" \
+ "\n -k show output in KB" \
+ "\n -m show output in MB" \
+ "\n -g show output in GB" \
+
#define free_example_usage \
"$ free\n" \
" total used free shared
buffers\n" \
diff --git a/procps/free.c b/procps/free.c
index be65f46..5e6cca9 100644
--- a/procps/free.c
+++ b/procps/free.c
@@ -16,10 +16,35 @@ int free_main(int argc UNUSED_PARAM, char **argv
IF_NOT_DESKTOP(UNUSED_PARAM))
{
struct sysinfo info;
unsigned mem_unit;
-
+ /*
+ * Convert numbers to a more readable format by dividing
+ * unit_steps times by 1024 (kB->MB->GB) and multiplying
+ * by the memory unit size afterwards
+ *
+ * TODO: Avoid overflows when mem >= 4 TB
+ */
+#define SI_UNIT(d) ( ( (d) >> (10*(unit_steps)))*(mem_unit) )
+ /* we like to use kbytes as our default unit */
+ int unit_steps = 1;
#if ENABLE_DESKTOP
- if (argv[1] && argv[1][0] == '-')
- bb_show_usage();
+ if (argv[1] && argv[1][0] == '-') {
+ switch (argv[1][1]) {
+ case 'b':
+ unit_steps = 0;
+ break;
+ case 'k': /* 2^10 */
+ unit_steps = 1;
+ break;
+ case 'm': /* 2^(2*10) */
+ unit_steps = 2;
+ break;
+ case 'g': /* 2^(3*10) */
+ unit_steps = 3;
+ break;
+ default:
+ bb_show_usage();
+ }
+ }
#endif
sysinfo(&info);
@@ -30,29 +55,6 @@ int free_main(int argc UNUSED_PARAM, char **argv
IF_NOT_DESKTOP(UNUSED_PARAM))
mem_unit = info.mem_unit;
}
- /* Convert values to kbytes */
- if (mem_unit == 1) {
- info.totalram >>= 10;
- info.freeram >>= 10;
-#if BB_MMU
- info.totalswap >>= 10;
- info.freeswap >>= 10;
-#endif
- info.sharedram >>= 10;
- info.bufferram >>= 10;
- } else {
- mem_unit >>= 10;
- /* TODO: Make all this stuff not overflow when mem >= 4 Tb */
- info.totalram *= mem_unit;
- info.freeram *= mem_unit;
-#if BB_MMU
- info.totalswap *= mem_unit;
- info.freeswap *= mem_unit;
-#endif
- info.sharedram *= mem_unit;
- info.bufferram *= mem_unit;
- }
-
printf(" %13s%13s%13s%13s%13s\n",
"total",
"used",
@@ -66,27 +68,29 @@ int free_main(int argc UNUSED_PARAM, char **argv
IF_NOT_DESKTOP(UNUSED_PARAM))
#define FIELDS_5 "%13lu%13lu%13lu%13lu%13lu\n"
#define FIELDS_3 (FIELDS_5 + 2*5)
#define FIELDS_2 (FIELDS_5 + 3*5)
+
printf("Mem: ");
printf(FIELDS_5,
- info.totalram,
- info.totalram - info.freeram,
- info.freeram,
- info.sharedram, info.bufferram
+ SI_UNIT(info.totalram),
+ SI_UNIT(info.totalram - info.freeram),
+ SI_UNIT(info.freeram),
+ SI_UNIT(info.sharedram),
+ SI_UNIT(info.bufferram)
);
/* Show alternate, more meaningful busy/free numbers by counting
* buffer cache as free memory (make it "-/+ buffers/cache"
* if/when we add support for "cached" column): */
printf("-/+ buffers: ");
printf(FIELDS_2,
- info.totalram - info.freeram - info.bufferram,
- info.freeram + info.bufferram
+ SI_UNIT(info.totalram - info.freeram - info.bufferram),
+ SI_UNIT(info.freeram + info.bufferram)
);
#if BB_MMU
printf("Swap:");
printf(FIELDS_3,
- info.totalswap,
- info.totalswap - info.freeswap,
- info.freeswap
+ SI_UNIT(info.totalswap),
+ SI_UNIT(info.totalswap - info.freeswap),
+ SI_UNIT(info.freeswap)
);
#endif
return EXIT_SUCCESS;
--
1.7.1
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox