From 1363bad02d8d5047625c59c76c4620d2a5c27bad Mon Sep 17 00:00:00 2001 From: utox39 Date: Tue, 7 Oct 2025 09:45:43 +0200 Subject: [PATCH 1/7] refactor(ascii): replace the deprecated readToEndAlloc with the new Reader --- src/ascii.zig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ascii.zig b/src/ascii.zig index c24fc50..f39198d 100644 --- a/src/ascii.zig +++ b/src/ascii.zig @@ -74,7 +74,12 @@ pub fn printAsciiAndModules(allocator: std.mem.Allocator, ascii_art_path: ?[]u8, if (ascii_art_path) |ascii| { var ascii_file = try std.fs.cwd().openFile(ascii, .{}); defer ascii_file.close(); - ascii_art_data = try ascii_file.readToEndAlloc(allocator, std.math.maxInt(usize)); + const file_size = (try ascii_file.stat()).size; + + var file_buf = try allocator.alloc(u8, file_size); + var reader = std.fs.File.Reader.init(ascii_file, file_buf); + const read = try reader.read(file_buf); + ascii_art_data = file_buf[0..read]; } else { ascii_art_data = @embedFile("./assets/ascii/guy_fawks.txt"); } From 48ab100e132cb9bd828cb7c416df9a26ea90b589 Mon Sep 17 00:00:00 2001 From: utox39 Date: Tue, 7 Oct 2025 09:50:06 +0200 Subject: [PATCH 2/7] refactor(config): replace the deprecated readToEndAlloc with the new Reader --- src/config.zig | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/config.zig b/src/config.zig index ab15185..3609dac 100644 --- a/src/config.zig +++ b/src/config.zig @@ -68,14 +68,20 @@ pub fn readConfigFile(allocator: std.mem.Allocator) !?std.json.Parsed(Config) { const config_abs_path = try std.mem.concat(allocator, u8, &.{ home, "/.config/zigfetch/config.json" }); defer allocator.free(config_abs_path); - const file = std.fs.openFileAbsolute(config_abs_path, .{ .mode = .read_only }) catch |err| switch (err) { + const config_file = std.fs.openFileAbsolute(config_abs_path, .{ .mode = .read_only }) catch |err| switch (err) { error.FileNotFound => return null, else => return err, }; - defer file.close(); + defer config_file.close(); - const data = try file.readToEndAlloc(allocator, std.math.maxInt(usize)); - defer allocator.free(data); + const file_size = (try config_file.stat()).size; - return try std.json.parseFromSlice(Config, allocator, data, .{ .allocate = .alloc_always }); + var file_buf = try allocator.alloc(u8, file_size); + var reader = std.fs.File.Reader.init(config_file, file_buf); + const read = try reader.read(file_buf); + const config_data = file_buf[0..read]; + + defer allocator.free(config_data); + + return try std.json.parseFromSlice(Config, allocator, config_data, .{ .allocate = .alloc_always }); } From 36ff1857b700d22cc57a70297f1d25c95c5a8cc9 Mon Sep 17 00:00:00 2001 From: utox39 Date: Wed, 8 Oct 2025 21:58:50 +0200 Subject: [PATCH 3/7] feat(utils): add a utility function to read files This function uses the new fs.File.Reader to replace the deprecated fs.File.readToEndAlloc --- src/utils.zig | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/utils.zig b/src/utils.zig index b9b455b..8721cf4 100644 --- a/src/utils.zig +++ b/src/utils.zig @@ -114,3 +114,15 @@ test "getLongestAsciiArtRowLen" { try std.testing.expectEqual(40, try getLongestAsciiArtRowLen(rows[0..])); } + +pub fn readFile(allocator: std.mem.Allocator, file: std.fs.File, size: usize) ![]const u8 { + var file_buf = try allocator.alloc(u8, size); + defer allocator.free(file_buf); + + var reader = std.fs.File.Reader.init(file, file_buf); + const read = try reader.read(file_buf); + + const data = file_buf[0..read]; + + return allocator.dupe(u8, data); +} From a5f4a60d462b6056f8348d778e6c8cbeaeacd12d Mon Sep 17 00:00:00 2001 From: utox39 Date: Wed, 8 Oct 2025 22:06:41 +0200 Subject: [PATCH 4/7] refactor(config): use utils.readFile to read the config file --- src/config.zig | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/config.zig b/src/config.zig index 3609dac..d538dc1 100644 --- a/src/config.zig +++ b/src/config.zig @@ -1,5 +1,6 @@ const std = @import("std"); const ascii = @import("ascii.zig"); +const utils = @import("utils.zig"); pub const Module = struct { type: []u8, @@ -76,11 +77,7 @@ pub fn readConfigFile(allocator: std.mem.Allocator) !?std.json.Parsed(Config) { const file_size = (try config_file.stat()).size; - var file_buf = try allocator.alloc(u8, file_size); - var reader = std.fs.File.Reader.init(config_file, file_buf); - const read = try reader.read(file_buf); - const config_data = file_buf[0..read]; - + const config_data = try utils.readFile(allocator, config_file, file_size); defer allocator.free(config_data); return try std.json.parseFromSlice(Config, allocator, config_data, .{ .allocate = .alloc_always }); From 3e55f6a9733035225440eec0b95dfe3577ac5205 Mon Sep 17 00:00:00 2001 From: utox39 Date: Wed, 8 Oct 2025 22:09:27 +0200 Subject: [PATCH 5/7] refactor(ascii): use utils.readFile to read the ascii art file --- src/ascii.zig | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/ascii.zig b/src/ascii.zig index f39198d..fd6558b 100644 --- a/src/ascii.zig +++ b/src/ascii.zig @@ -72,14 +72,10 @@ pub fn printAsciiAndModules(allocator: std.mem.Allocator, ascii_art_path: ?[]u8, var ascii_art_data: []const u8 = undefined; if (ascii_art_path) |ascii| { - var ascii_file = try std.fs.cwd().openFile(ascii, .{}); + const ascii_file = try std.fs.cwd().openFile(ascii, .{}); defer ascii_file.close(); const file_size = (try ascii_file.stat()).size; - - var file_buf = try allocator.alloc(u8, file_size); - var reader = std.fs.File.Reader.init(ascii_file, file_buf); - const read = try reader.read(file_buf); - ascii_art_data = file_buf[0..read]; + ascii_art_data = try utils.readFile(allocator, ascii_file, file_size); } else { ascii_art_data = @embedFile("./assets/ascii/guy_fawks.txt"); } From 61ceb027a624eb9f42138cda02e4d3546a0a7cc9 Mon Sep 17 00:00:00 2001 From: utox39 Date: Wed, 8 Oct 2025 22:13:23 +0200 Subject: [PATCH 6/7] refactor(linux): use utils.readFile to read the files --- src/linux/hardware.zig | 52 ++++++++++++++++++++++++++++++------------ src/linux/system.zig | 8 ++++--- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/linux/hardware.zig b/src/linux/hardware.zig index d3c7fc5..6da6d86 100644 --- a/src/linux/hardware.zig +++ b/src/linux/hardware.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const utils = @import("../utils.zig"); const c_unistd = @cImport(@cInclude("unistd.h")); const c_statvfs = @cImport(@cInclude("sys/statvfs.h")); const c_libpci = @cImport(@cInclude("pci/pci.h")); @@ -44,9 +45,16 @@ pub fn getCpuInfo(allocator: std.mem.Allocator) !CpuInfo { // Reads /proc/cpuinfo const cpuinfo_path = "/proc/cpuinfo"; - var file = try std.fs.cwd().openFile(cpuinfo_path, .{}); - defer file.close(); - const cpuinfo_data = try file.readToEndAlloc(allocator, std.math.maxInt(usize)); + const cpuinfo_file = try std.fs.cwd().openFile(cpuinfo_path, .{ .mode = .read_only }); + defer cpuinfo_file.close(); + + // NOTE: procfs is a pseudo-filesystem, so it is not possible to determine the size of a file + // https://docs.kernel.org/filesystems/proc.html + // https://en.wikipedia.org/wiki/Procfs + // + // Only the first section (core 0) will be parsed + // 512 is more than enough + const cpuinfo_data = try utils.readFile(allocator, cpuinfo_file, 512); defer allocator.free(cpuinfo_data); // Parsing /proc/cpuinfo @@ -77,6 +85,7 @@ pub fn getCpuInfo(allocator: std.mem.Allocator) !CpuInfo { var cpu_max_freq: f32 = 0.0; + // NOTE: this is the preferred approach beacause it is the most accurate const cpuinfo_max_freq_path = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq"; var cmf_exists: bool = true; @@ -89,14 +98,13 @@ pub fn getCpuInfo(allocator: std.mem.Allocator) !CpuInfo { if (cmf_exists) { // Reads /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq - var file2 = try std.fs.cwd().openFile(cpuinfo_max_freq_path, .{}); - - defer file2.close(); - const cpuinfo_max_freq_data = try file2.readToEndAlloc(allocator, std.math.maxInt(usize)); - defer allocator.free(cpuinfo_max_freq_data); + const maxfreq_file = try std.fs.cwd().openFile(cpuinfo_max_freq_path, .{ .mode = .read_only }); + defer maxfreq_file.close(); + const maxfreq_data = try utils.readFile(allocator, maxfreq_file, 32); + defer allocator.free(maxfreq_data); // Parsing /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq - const trimmed = std.mem.trim(u8, cpuinfo_max_freq_data, " \n\r"); + const trimmed = std.mem.trim(u8, maxfreq_data, " \n\r"); const cpu_max_freq_khz: f32 = try std.fmt.parseFloat(f32, trimmed); cpu_max_freq = cpu_max_freq_khz / 1_000_000; } else { @@ -203,9 +211,16 @@ fn parseGpuName(allocator: std.mem.Allocator, name: []u8) !?[]u8 { 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)); + const meminfo_file = try std.fs.cwd().openFile(meminfo_path, .{ .mode = .read_only }); + defer meminfo_file.close(); + + // NOTE: procfs is a pseudo-filesystem, so it is not possible to determine the size of a file + // https://docs.kernel.org/filesystems/proc.html + // https://en.wikipedia.org/wiki/Procfs + // + // We only need to read the first few lines + // 512 is more than enough + const meminfo_data = try utils.readFile(allocator, meminfo_file, 512); defer allocator.free(meminfo_data); // Parsing /proc/meminfo @@ -265,9 +280,16 @@ pub fn getRamInfo(allocator: std.mem.Allocator) !RamInfo { pub fn getSwapInfo(allocator: std.mem.Allocator) !?SwapInfo { // 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)); + const meminfo_file = try std.fs.cwd().openFile(meminfo_path, .{ .mode = .read_only }); + defer meminfo_file.close(); + + // NOTE: procfs is a pseudo-filesystem, so it is not possible to determine the size of a file + // https://docs.kernel.org/filesystems/proc.html + // https://en.wikipedia.org/wiki/Procfs + // + // We only need to read the first few lines + // 512 is ok + const meminfo_data = try utils.readFile(allocator, meminfo_file, 512); defer allocator.free(meminfo_data); // Parsing /proc/meminfo diff --git a/src/linux/system.zig b/src/linux/system.zig index 5ebc159..7d6ee14 100644 --- a/src/linux/system.zig +++ b/src/linux/system.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const utils = @import("../utils.zig"); const c_sysinfo = @cImport(@cInclude("sys/sysinfo.h")); const c_utsname = @cImport(@cInclude("sys/utsname.h")); @@ -77,9 +78,10 @@ pub fn getKernelInfo(allocator: std.mem.Allocator) !KernelInfo { pub fn getOsInfo(allocator: std.mem.Allocator) ![]u8 { const os_release_path = "/etc/os-release"; - const file = try std.fs.cwd().openFile(os_release_path, .{}); - defer file.close(); - const os_release_data = try file.readToEndAlloc(allocator, std.math.maxInt(usize)); + const os_release_file = try std.fs.cwd().openFile(os_release_path, .{ .mode = .read_only }); + defer os_release_file.close(); + const size = (try os_release_file.stat()).size; + const os_release_data = try utils.readFile(allocator, os_release_file, size); defer allocator.free(os_release_data); var pretty_name: ?[]const u8 = null; From 1d7a175d291069c0eedd641fcc60e631fac47348 Mon Sep 17 00:00:00 2001 From: utox39 Date: Wed, 8 Oct 2025 22:23:36 +0200 Subject: [PATCH 7/7] feat(ascii): read the ascii art file in read-only mode --- src/ascii.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ascii.zig b/src/ascii.zig index fd6558b..9bdb2f8 100644 --- a/src/ascii.zig +++ b/src/ascii.zig @@ -72,7 +72,7 @@ pub fn printAsciiAndModules(allocator: std.mem.Allocator, ascii_art_path: ?[]u8, var ascii_art_data: []const u8 = undefined; if (ascii_art_path) |ascii| { - const ascii_file = try std.fs.cwd().openFile(ascii, .{}); + const ascii_file = try std.fs.cwd().openFile(ascii, .{ .mode = .read_only }); defer ascii_file.close(); const file_size = (try ascii_file.stat()).size; ascii_art_data = try utils.readFile(allocator, ascii_file, file_size);