//! Process-level runtime types: what a user program receives at entry. Mirrors //! the spirit of `std.process.Init.Minimal` in danos terms — std's `Args` holds //! no data on freestanding targets, so the type is danos's own. const std = @import("std"); /// Everything a program receives at entry. Passed to /// `pub fn main(init: runtime.process.Init)`; programs that need nothing keep /// `pub fn main() void`. An `environment` field is added here once the kernel /// passes a non-empty envp (today it is always empty — see docs/sysv.md). pub const Init = struct { arguments: Arguments, }; /// The process arguments (argc/argv), parsed from the kernel-built System V /// entry block. The bytes live in the entry block at the top of the stack page, /// NUL-terminated, valid for the process's lifetime. pub const Arguments = struct { /// argc — at least 1: argument 0 is the path or name this binary was /// spawned as. count: usize, /// The argv pointers in the entry block (NULL-terminated after `count` /// entries). vector: [*]const [*:0]const u8, /// Argument `index` (0 = the program's own path/name), or null if out of /// range. pub fn get(arguments: Arguments, index: usize) ?[:0]const u8 { if (index >= arguments.count) return null; return std.mem.span(arguments.vector[index]); } pub fn iterate(arguments: Arguments) Iterator { return .{ .arguments = arguments }; } pub const Iterator = struct { arguments: Arguments, index: usize = 0, pub fn next(iterator: *Iterator) ?[:0]const u8 { const argument = iterator.arguments.get(iterator.index) orelse return null; iterator.index += 1; return argument; } }; };