Serenity Operating System
at master 86 lines 3.3 kB view raw
1/* 2 * Copyright (c) 2020-2022, the SerenityOS developers. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/DeprecatedString.h> 8#include <AK/JsonObject.h> 9#include <AK/QuickSort.h> 10#include <LibCore/ArgsParser.h> 11#include <LibCore/File.h> 12#include <LibCore/System.h> 13#include <LibMain/Main.h> 14 15ErrorOr<int> serenity_main(Main::Arguments arguments) 16{ 17 TRY(Core::System::pledge("stdio rpath")); 18 TRY(Core::System::unveil("/proc", "r")); 19 TRY(Core::System::unveil(nullptr, nullptr)); 20 21 StringView pid; 22 static bool extended = false; 23 24 Core::ArgsParser args_parser; 25 args_parser.add_option(extended, "Extended output", nullptr, 'x'); 26 args_parser.add_positional_argument(pid, "PID", "PID", Core::ArgsParser::Required::Yes); 27 args_parser.parse(arguments); 28 29 auto file = TRY(Core::File::open(DeprecatedString::formatted("/proc/{}/vm", pid), Core::File::OpenMode::Read)); 30 31 outln("{}:", pid); 32 33 auto padding = " "; 34 35 if (extended) { 36 outln("Address{} Size Resident Dirty Access VMObject Type Purgeable CoW Pages Name", padding); 37 } else { 38 outln("Address{} Size Access Name", padding); 39 } 40 41 auto file_contents = TRY(file->read_until_eof()); 42 auto json = TRY(JsonValue::from_string(file_contents)); 43 44 Vector<JsonValue> sorted_regions = json.as_array().values(); 45 quick_sort(sorted_regions, [](auto& a, auto& b) { 46 return a.as_object().get_addr("address"sv).value_or(0) < b.as_object().get_addr("address"sv).value_or(0); 47 }); 48 49 for (auto& value : sorted_regions) { 50 auto& map = value.as_object(); 51 auto address = map.get_addr("address"sv).value_or(0); 52 auto size = map.get("size"sv).value_or({}).to_deprecated_string(); 53 54 auto access = DeprecatedString::formatted("{}{}{}{}{}", 55 (map.get_bool("readable"sv).value_or(false) ? "r" : "-"), 56 (map.get_bool("writable"sv).value_or(false) ? "w" : "-"), 57 (map.get_bool("executable"sv).value_or(false) ? "x" : "-"), 58 (map.get_bool("shared"sv).value_or(false) ? "s" : "-"), 59 (map.get_bool("syscall"sv).value_or(false) ? "c" : "-")); 60 61 out("{:p} ", address); 62 out("{:>10} ", size); 63 if (extended) { 64 auto resident = map.get("amount_resident"sv).value_or({}).to_deprecated_string(); 65 auto dirty = map.get("amount_dirty"sv).value_or({}).to_deprecated_string(); 66 auto vmobject = map.get_deprecated_string("vmobject"sv).value_or({}); 67 if (vmobject.ends_with("VMObject"sv)) 68 vmobject = vmobject.substring(0, vmobject.length() - 8); 69 auto purgeable = map.get("purgeable"sv).value_or({}).to_deprecated_string(); 70 auto cow_pages = map.get("cow_pages"sv).value_or({}).to_deprecated_string(); 71 out("{:>10} ", resident); 72 out("{:>10} ", dirty); 73 out("{:6} ", access); 74 out("{:14} ", vmobject); 75 out("{:10} ", purgeable); 76 out("{:>10} ", cow_pages); 77 } else { 78 out("{:6} ", access); 79 } 80 auto name = map.get_deprecated_string("name"sv).value_or({}); 81 out("{:20}", name); 82 outln(); 83 } 84 85 return 0; 86}