From 92b348924e350f14caee6481a08a4b39be8f843d Mon Sep 17 00:00:00 2001 From: utox39 Date: Sat, 8 Mar 2025 21:51:04 +0100 Subject: [PATCH] feat(linux): add ram info --- src/linux/linux.zig | 68 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/linux/linux.zig b/src/linux/linux.zig index 71f50cf..13e5b49 100644 --- a/src/linux/linux.zig +++ b/src/linux/linux.zig @@ -15,6 +15,12 @@ pub const CpuInfo = struct { cpu_max_freq: f32, }; +pub const RamInfo = struct { + ram_size: f64, + ram_usage: f64, + ram_usage_percentage: u8, +}; + pub fn getUsername(allocator: std.mem.Allocator) ![]u8 { const username = try std.process.getEnvVarOwned(allocator, "USER"); return username; @@ -122,3 +128,65 @@ pub fn getCpuInfo(allocator: std.mem.Allocator) !CpuInfo { .cpu_max_freq = cpu_max_freq, }; } + +pub fn getRamInfo(allocator: std.mem.Allocator) !RamInfo { + // Reads /proc/meminfo + const meminfo_path = "/proc/meminfo"; + const file = try std.fs.cwd().openFile(meminfo_path, .{}); + defer file.close(); + const meminfo_data = try file.readToEndAlloc(allocator, std.math.maxInt(usize)); + defer allocator.free(meminfo_data); + + // Parsing /proc/meminfo + var total_mem: f64 = 0.0; + var free_mem: f64 = 0.0; // remove? + var available_mem: f64 = 0.0; + + var total_mem_str: ?[]const u8 = null; + var free_mem_str: ?[]const u8 = null; + var available_mem_str: ?[]const u8 = null; + + var lines = std.mem.split(u8, meminfo_data, "\n"); + while (lines.next()) |line| { + const trimmed = std.mem.trim(u8, line, " \t"); + if (std.mem.startsWith(u8, trimmed, "MemTotal")) { + var parts = std.mem.split(u8, trimmed, ":"); + _ = parts.next(); // discards the key + if (parts.next()) |value| { + total_mem_str = std.mem.trim(u8, value[0..(value.len - 3)], " "); + total_mem = try std.fmt.parseFloat(f64, total_mem_str.?); + } + } else if (std.mem.startsWith(u8, trimmed, "MemFree")) { + var parts = std.mem.split(u8, trimmed, ":"); + _ = parts.next(); // discards the key + if (parts.next()) |value| { + free_mem_str = std.mem.trim(u8, value[0..(value.len - 3)], " "); + free_mem = try std.fmt.parseFloat(f64, free_mem_str.?); + } + } else if (std.mem.startsWith(u8, trimmed, "MemAvailable")) { + var parts = std.mem.split(u8, trimmed, ":"); + _ = parts.next(); // discards the key + if (parts.next()) |value| { + available_mem_str = std.mem.trim(u8, value[0..(value.len - 3)], " "); + available_mem = try std.fmt.parseFloat(f64, available_mem_str.?); + } + } + + if ((total_mem_str != null) and (free_mem_str != null) and (available_mem_str != null)) { + break; + } + } + + var used_mem = total_mem - available_mem; + + // Converts KB in GB + total_mem /= (1024 * 1024); + used_mem /= (1024 * 1024); + const ram_usage_percentage: u8 = @as(u8, @intFromFloat((used_mem * 100) / total_mem)); + + return RamInfo{ + .ram_size = total_mem, + .ram_usage = used_mem, + .ram_usage_percentage = ram_usage_percentage, + }; +}