diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 13e88906..c399f679 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -47,3 +47,4 @@ luna_app(socket-client.cpp socket-client) luna_app(input.cpp input) luna_app(shmem-test.cpp shmem-test) luna_app(touch.cpp touch) +luna_app(free.cpp free) diff --git a/apps/free.cpp b/apps/free.cpp new file mode 100644 index 00000000..d35809be --- /dev/null +++ b/apps/free.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +#include + +Result luna_main(int argc, char** argv) +{ + bool reserved { false }; + bool human_readable { false }; + + os::ArgumentParser parser; + parser.add_description("Query the amount of memory available and used in the system."); + parser.add_system_program_info("free"_sv); + parser.add_switch_argument(reserved, 'r', "show-reserved"_sv, "show reserved system memory"_sv); + parser.add_switch_argument(human_readable, 'h', "human-readable"_sv, "show output in human-readable units"_sv); + parser.parse(argc, argv); + + struct membuf buf; + memstat(&buf); + + if (human_readable) + { + auto total = TRY(to_dynamic_unit(buf.mem_total, 10, false, Unit::Binary, true)); + auto free = TRY(to_dynamic_unit(buf.mem_free, 10, false, Unit::Binary, true)); + auto used = TRY(to_dynamic_unit(buf.mem_used, 10, false, Unit::Binary, true)); + + os::println("%s total memory, out of which:", total.chars()); + os::println("%s used", used.chars()); + os::println("%s free", free.chars()); + } + else + { + os::println("%lu total memory, out of which:", buf.mem_total); + os::println("%lu used", buf.mem_used); + os::println("%lu free", buf.mem_free); + } + + if (reserved) + { + if (human_readable) + { + auto reserved_string = TRY(to_dynamic_unit(buf.mem_reserved, 10, false, Unit::Binary, true)); + + os::println("%s reserved", reserved_string.chars()); + } + else { os::println("%lu reserved", buf.mem_reserved); } + } + + return 0; +}