From 8c5bef6cb41a9d059c91f18f71fb116973ce22c7 Mon Sep 17 00:00:00 2001 From: LN Liberda Date: Fri, 22 May 2026 21:41:28 +0200 Subject: [PATCH] Zig 0.16: fs/io --- src/bin_export.zig | 6 +++--- src/bin_reader.zig | 12 +++++------- src/json_export.zig | 6 +++--- src/json_import.zig | 6 +++--- src/main.zig | 34 +++++++++++++++++----------------- 5 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/bin_export.zig b/src/bin_export.zig index a10128b..12fc8b5 100644 --- a/src/bin_export.zig +++ b/src/bin_export.zig @@ -10,7 +10,7 @@ const ui = @import("ui.zig"); const c = @import("c.zig").c; pub const global = struct { - var fd: std.fs.File = undefined; + var fd: std.Io.File = undefined; var index: std.ArrayListUnmanaged(u8) = .empty; var file_off: u64 = 0; var lock: std.Thread.Mutex = .{}; @@ -457,9 +457,9 @@ pub fn done(threads: []sink.Thread) void { global.fd.close(); } -pub fn setupOutput(fd: std.fs.File) void { +pub fn setupOutput(fd: std.Io.File) void { global.fd = fd; - fd.writeAll(SIGNATURE) catch |e| + fd.writeStreamingAll(main.io, SIGNATURE) catch |e| ui.die("Error writing to file: {s}.\n", .{ ui.errorString(e) }); global.file_off = 8; diff --git a/src/bin_reader.zig b/src/bin_reader.zig index cdbe117..5d5aac9 100644 --- a/src/bin_reader.zig +++ b/src/bin_reader.zig @@ -39,7 +39,7 @@ const ItemKey = bin_export.ItemKey; // This file only implements (2) at the moment. pub const global = struct { - var fd: std.fs.File = undefined; + var fd: std.Io.File = undefined; var index: []u8 = undefined; var blocks: [8]Block = [1]Block{.{}}**8; var counter: u64 = 0; @@ -501,21 +501,19 @@ pub fn import() void { } // Assumes that the file signature has already been read and validated. -pub fn open(fd: std.fs.File) !void { +pub fn open(fd: std.Io.File) !void { global.fd = fd; - // Do not use fd.getEndPos() because that requires newer kernels supporting statx() #261. - try fd.seekFromEnd(0); - const size = try fd.getPos(); + const size = try fd.length(main.io); if (size < 16) return error.EndOfStream; // Read index block var buf: [4]u8 = undefined; - if (try fd.preadAll(&buf, size - 4) != 4) return error.EndOfStream; + if (try fd.readPositionalAll(main.io, &buf, size - 4) != 4) return error.EndOfStream; const index_header = bigu32(buf); if ((index_header >> 28) != 1 or (index_header & 7) != 0) die(); const len = (index_header & 0x0fffffff) - 8; // excluding block header & footer if (len >= size) die(); global.index = main.allocator.alloc(u8, len) catch unreachable; - if (try fd.preadAll(global.index, size - len - 4) != global.index.len) return error.EndOfStream; + if (try fd.readPositionalAll(main.io, global.index, size - len - 4) != global.index.len) return error.EndOfStream; } diff --git a/src/json_export.zig b/src/json_export.zig index 3937b3f..904cc0e 100644 --- a/src/json_export.zig +++ b/src/json_export.zig @@ -62,7 +62,7 @@ const ZstdWriter = struct { }; pub const Writer = struct { - fd: std.fs.File, + fd: std.Io.File, zstd: ?*ZstdWriter = null, // Must be large enough to hold PATH_MAX*6 plus some overhead. // (The 6 is because, in the worst case, every byte expands to a "\u####" @@ -138,7 +138,7 @@ pub const Writer = struct { ctx.write(buf[index..]); } - fn init(out: std.fs.File) *Writer { + fn init(out: std.Io.File) *Writer { var ctx = main.allocator.create(Writer) catch unreachable; ctx.* = .{ .fd = out }; if (main.config.compress) ctx.zstd = ZstdWriter.create(); @@ -265,6 +265,6 @@ pub fn done() void { main.allocator.destroy(global.writer); } -pub fn setupOutput(out: std.fs.File) void { +pub fn setupOutput(out: std.Io.File) void { global.writer = Writer.init(out); } diff --git a/src/json_import.zig b/src/json_import.zig index 28224e6..d74b9a2 100644 --- a/src/json_import.zig +++ b/src/json_import.zig @@ -37,7 +37,7 @@ const ZstdReader = struct { main.allocator.destroy(r); } - fn read(r: *ZstdReader, f: std.fs.File, out: []u8) !usize { + fn read(r: *ZstdReader, f: std.Io.File, out: []u8) !usize { while (true) { if (r.in.size == r.in.pos) { r.in.pos = 0; @@ -63,7 +63,7 @@ const ZstdReader = struct { // strings. const Parser = struct { - rd: std.fs.File, + rd: std.Io.File, zstd: ?*ZstdReader = null, rdoff: usize = 0, rdsize: usize = 0, @@ -528,7 +528,7 @@ fn item(ctx: *Ctx, parent: ?*sink.Dir, dev: u64) void { } -pub fn import(fd: std.fs.File, head: []const u8) void { +pub fn import(fd: std.Io.File, head: []const u8) void { const sink_threads = sink.createThreads(1); defer sink.done(); diff --git a/src/main.zig b/src/main.zig index 8848794..25771ea 100644 --- a/src/main.zig +++ b/src/main.zig @@ -121,8 +121,8 @@ pub const config = struct { pub var state: enum { scan, browse, refresh, shell, delete } = .scan; -const stdin = if (@hasDecl(std.io, "getStdIn")) std.io.getStdIn() else std.fs.File.stdin(); -const stdout = if (@hasDecl(std.io, "getStdOut")) std.io.getStdOut() else std.fs.File.stdout(); +const stdin = std.Io.File.stdin(); +const stdout = std.Io.File.stdout(); // Simple generic argument parser, supports getopt_long() style arguments. const Args = struct { @@ -326,12 +326,12 @@ fn argConfig(args: *Args, opt: Args.Option, infile: bool) !void { } fn tryReadArgsFile(path: [:0]const u8) void { - var f = std.fs.cwd().openFileZ(path, .{}) catch |e| switch (e) { + var f = std.Io.Dir.cwd().openFile(io, path, .{}) catch |e| switch (e) { error.FileNotFound => return, error.NotDir => return, else => ui.die("Error opening {s}: {s}\nRun with --ignore-config to skip reading config files.\n", .{ path, ui.errorString(e) }), }; - defer f.close(); + defer f.close(io); var line_buf: [4096]u8 = undefined; var line_rd = util.LineReader.init(io, f, &line_buf); @@ -374,12 +374,12 @@ fn tryReadArgsFile(path: [:0]const u8) void { } fn version() noreturn { - stdout.writeAll("ncdu " ++ program_version ++ "\n") catch {}; + stdout.writeStreamingAll(io, "ncdu " ++ program_version ++ "\n") catch {}; std.process.exit(0); } fn help() noreturn { - stdout.writeAll( + stdout.writeStreamingAll(io, \\ncdu \\ \\Mode selection: @@ -438,11 +438,11 @@ fn help() noreturn { fn readExcludeFile(path: [:0]const u8) !void { - const f = try std.fs.cwd().openFileZ(path, .{}); - defer f.close(); + const f = try std.Io.Dir.cwd().openFile(io, path, .{}); + defer f.close(io); var line_buf: [4096]u8 = undefined; - var line_rd = util.LineReader.init(f, &line_buf); + var line_rd = util.LineReader.init(io, f, &line_buf); while (try line_rd.read()) |line| { if (line.len > 0) exclude.addPattern(line); @@ -452,17 +452,17 @@ fn readExcludeFile(path: [:0]const u8) !void { fn readImport(path: [:0]const u8) !void { const fd = if (std.mem.eql(u8, "-", path)) stdin - else try std.fs.cwd().openFileZ(path, .{}); - errdefer fd.close(); + else try std.Io.Dir.cwd().openFile(io, path, .{}); + errdefer fd.close(io); var buf: [8]u8 = undefined; - if (8 != try fd.readAll(&buf)) return error.EndOfStream; + if (8 != try fd.readPositionalAll(io, &buf, 0)) return error.EndOfStream; if (std.mem.eql(u8, &buf, bin_export.SIGNATURE)) { try bin_reader.open(fd); config.binreader = true; } else { json_import.import(fd, &buf); - fd.close(); + fd.close(io); } } @@ -540,8 +540,8 @@ pub fn main(init: std.process.Init) void { if (@import("builtin").os.tag != .linux and config.exclude_kernfs) ui.die("The --exclude-kernfs flag is currently only supported on Linux.\n", .{}); - const out_tty = stdout.isTty(); - const in_tty = stdin.isTty(); + const out_tty = stdout.isTty(io) catch unreachable; + const in_tty = stdin.isTty(io) catch unreachable; if (config.scan_ui == null) { if (export_json orelse export_bin) |f| { if (!out_tty or std.mem.eql(u8, f, "-")) config.scan_ui = .none @@ -558,14 +558,14 @@ pub fn main(init: std.process.Init) void { if (export_json) |f| { const file = if (std.mem.eql(u8, f, "-")) stdout - else std.fs.cwd().createFileZ(f, .{}) + else std.Io.Dir.cwd().createFile(io, f, .{}) catch |e| ui.die("Error opening export file: {s}.\n", .{ui.errorString(e)}); json_export.setupOutput(file); sink.global.sink = .json; } else if (export_bin) |f| { const file = if (std.mem.eql(u8, f, "-")) stdout - else std.fs.cwd().createFileZ(f, .{}) + else std.Io.Dir.cwd().createFile(io, f, .{}) catch |e| ui.die("Error opening export file: {s}.\n", .{ui.errorString(e)}); bin_export.setupOutput(file); sink.global.sink = .bin;