lib: banner purge + WHY-only comment sweep (rule 8)
Every // ---- section banner dies (132 -> 0): names carry the WHAT. Narration deleted (filename restatements, run-with lines, what-the- next-line-does); every ref/hare cite, task cite, divergence, ABI/ layout contract, and ownership qualifier kept (borrowed-view lines restored where the sweep over-cut). Comment-only proven: all 442 walk-workdir .s and 32 import-probe .s byte-identical before/after; libbyteid 56-roster all-ID.
This commit is contained in:
34
lib/os/os.ww
34
lib/os/os.ww
@@ -1,6 +1,5 @@
|
||||
// os — process and filesystem facade. The body of each call lands
|
||||
// either in libwwrt.a (rt_syscall trampoline) or libc bindings,
|
||||
// depending on how the program was linked.
|
||||
// The body of each call lands either in libwwrt.a (rt_syscall
|
||||
// trampoline) or libc bindings, depending on how the program was linked.
|
||||
|
||||
package os;
|
||||
|
||||
@@ -155,10 +154,8 @@ export fn close(fd: i32) i32 = {
|
||||
return syscall1(nr.CLOSE, fd: i64): i32;
|
||||
};
|
||||
|
||||
// dup2(2): make `newfd` refer to the same description as `oldfd`,
|
||||
// closing `newfd` first if open. Returns `newfd` on success or a
|
||||
// negative errno. Used by w6c_ww to redirect stdout into an output
|
||||
// file without changing the cgen emit path.
|
||||
// Used by w6c_ww to redirect stdout into an output file without
|
||||
// changing the cgen emit path.
|
||||
export fn dup2(oldfd: i32, newfd: i32) i32 = {
|
||||
return syscall2(nr.DUP2, oldfd: i64, newfd: i64): i32;
|
||||
};
|
||||
@@ -208,9 +205,8 @@ export fn tryopen(path: str, flags: flag, mode: i32) (i32 | oserror) = {
|
||||
return fd;
|
||||
};
|
||||
|
||||
// lseek — set/inspect the fd's position. Returns the new offset or
|
||||
// a negative errno. We use this for fstat-free file-size discovery
|
||||
// (open ⇒ lseek to end ⇒ lseek back).
|
||||
// Used for fstat-free file-size discovery (open ⇒ lseek to end ⇒
|
||||
// lseek back).
|
||||
export fn lseek(fd: i32, off: i64, w: whence) i64 = {
|
||||
return syscall3(nr.LSEEK, fd: i64, off, (w as i32): i64);
|
||||
};
|
||||
@@ -273,7 +269,6 @@ export fn strerror(err: errno) str = {
|
||||
return "Unknown error";
|
||||
};
|
||||
|
||||
// filesize — byte length of an open fd via lseek-to-end-and-back.
|
||||
export fn filesize(fd: i32) (i64 | oserror) = {
|
||||
let end: i64 = lseek(fd, 0i64, whence.END);
|
||||
if (end < 0) { return end: oserror; };
|
||||
@@ -282,9 +277,8 @@ export fn filesize(fd: i32) (i64 | oserror) = {
|
||||
return end;
|
||||
};
|
||||
|
||||
// readall — keep reading until `n` bytes have arrived or the fd
|
||||
// closes early. Hare name (io::readall); the buffer is caller-
|
||||
// supplied, matching the Plan 9 subset convention.
|
||||
// Hare name (io::readall); the buffer is caller-supplied, matching
|
||||
// the Plan 9 subset convention.
|
||||
export fn readall(fd: i32, buf: *u8, n: u64) (i64 | oserror) = {
|
||||
let got: u64 = 0u64;
|
||||
for (got < n) {
|
||||
@@ -296,8 +290,7 @@ export fn readall(fd: i32, buf: *u8, n: u64) (i64 | oserror) = {
|
||||
return got: i64;
|
||||
};
|
||||
|
||||
// writeall — keep writing until `n` bytes have been accepted or the
|
||||
// fd refuses progress. Hare name (io::writeall).
|
||||
// Hare name (io::writeall).
|
||||
export fn writeall(fd: i32, buf: *u8, n: u64) (i64 | oserror) = {
|
||||
let sent: u64 = 0u64;
|
||||
for (sent < n) {
|
||||
@@ -309,8 +302,6 @@ export fn writeall(fd: i32, buf: *u8, n: u64) (i64 | oserror) = {
|
||||
return sent: i64;
|
||||
};
|
||||
|
||||
// ---- process and filesystem helpers used by the `ww` driver ----------
|
||||
|
||||
// access(2): returns 0 if the file is reachable, negative errno
|
||||
// otherwise. mode is the bitset described in <unistd.h> (F_OK=0).
|
||||
// Mirrors Hare's os::access (ref/hare/os/+linux/fs.ha:access).
|
||||
@@ -531,8 +522,6 @@ export fn getdents64(fd: i32, buf: *u8, n: u64) i64 = {
|
||||
return syscall3(nr.GETDENTS64, fd: i64, buf: i64, n: i64);
|
||||
};
|
||||
|
||||
// ---- environment ------------------------------------------------------
|
||||
|
||||
// rt_envp — runtime-side getter. rt/start.s captures envp into a DATAW
|
||||
// slot before calling main; this binding lifts the captured pointer
|
||||
// into ww. Same FFI shape as rt_syscall / rt_malloc / rt_abort: a TEXT
|
||||
@@ -688,8 +677,6 @@ export fn args() []str = {
|
||||
return r;
|
||||
};
|
||||
|
||||
// ---- stat / lstat / fstat / exists -----------------------------------
|
||||
//
|
||||
// Ports of Hare's stat family (ref/hare/fs/fs.ha:172,196 +
|
||||
// ref/hare/sys/+linux/stat.ha:24-58). The Hare surface returns
|
||||
// `filestat` by value; ww's cgreturn ABI tops out at 24B today (see
|
||||
@@ -830,8 +817,7 @@ type kstat = struct {
|
||||
let emptypath: [1]u8 = [0u8];
|
||||
|
||||
// fillfilestat — copy a 144B kstat into the 80B Hare-shaped
|
||||
// filestat. Internal helper used by all three public entry points.
|
||||
// Mirrors Hare's st_to_filestat (ref/hare/os/+linux/dirfdfs.ha:259):
|
||||
// filestat. Mirrors Hare's st_to_filestat (ref/hare/os/+linux/dirfdfs.ha:259):
|
||||
// newfstatat populates every field, so the mask is the OR-fold of
|
||||
// all seven Hare stat_mask bits.
|
||||
fn fillfilestat(out: *filestat, k: *kstat) void = {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// ostest — exercises lib/os surface that doesn't have a dedicated
|
||||
// test elsewhere. Covers [[os.getenv]] and a direct
|
||||
// [[os.alloc]] / [[os.free]] roundtrip. memio's tests indirectly
|
||||
// cover alloc/free; the direct row here pins the FFI shape under
|
||||
// lib/os itself so future bindings refactors can't quietly drift.
|
||||
// memio's tests indirectly cover alloc/free; the direct row here pins
|
||||
// the FFI shape under lib/os itself so future bindings refactors can't
|
||||
// quietly drift.
|
||||
//
|
||||
// getenv env contract (ww ships no setenv primitive, deliberately):
|
||||
//
|
||||
@@ -45,8 +43,6 @@ fn ostestwait(pid: i32, status: *i32) i32 = {
|
||||
return -1;
|
||||
};
|
||||
|
||||
// ---- getenv: set var → matching value -------------------------------
|
||||
|
||||
@test fn test_getenv_set() void = {
|
||||
let r = os.getenv("WW_TEST_GETENV");
|
||||
match (r) {
|
||||
@@ -57,11 +53,9 @@ fn ostestwait(pid: i32, status: *i32) i32 = {
|
||||
};
|
||||
};
|
||||
|
||||
// ---- getenv: empty value (set but zero-length) ----------------------
|
||||
//
|
||||
// POSIX permits an env var with an empty value (`name=` in environ).
|
||||
// getenv must return the empty str, NOT void — void is reserved for
|
||||
// "name not present at all". This row exercises the boundary.
|
||||
// "name not present at all".
|
||||
|
||||
@test fn test_getenv_empty() void = {
|
||||
let r = os.getenv("WW_TEST_EMPTY");
|
||||
@@ -73,8 +67,6 @@ fn ostestwait(pid: i32, status: *i32) i32 = {
|
||||
};
|
||||
};
|
||||
|
||||
// ---- getenv: unset var → void ---------------------------------------
|
||||
|
||||
@test fn test_getenv_unset() void = {
|
||||
let r = os.getenv("WW_TEST_NOT_SET");
|
||||
match (r) {
|
||||
@@ -83,8 +75,6 @@ fn ostestwait(pid: i32, status: *i32) i32 = {
|
||||
};
|
||||
};
|
||||
|
||||
// ---- getenv: prefix-collision guard ---------------------------------
|
||||
//
|
||||
// Probes that "WW_TEST_GETEN" (a prefix of WW_TEST_GETENV) doesn't
|
||||
// match. Without the explicit `entry[name.len] == '='` check in
|
||||
// getenv, a naive prefix matcher would return the value of any
|
||||
@@ -103,8 +93,6 @@ fn ostestwait(pid: i32, status: *i32) i32 = {
|
||||
};
|
||||
};
|
||||
|
||||
// ---- getenvs: direct non-vacuous coverage of the []str shape --------
|
||||
//
|
||||
// getenvs() is public API (task #28) and the single env walker getenv
|
||||
// routes through. getenv's cases exercise the walk transitively, but
|
||||
// none asserts the []str RETURN shape — its count or "NAME=VALUE" entry
|
||||
@@ -139,8 +127,6 @@ fn ostestwait(pid: i32, status: *i32) i32 = {
|
||||
};
|
||||
};
|
||||
|
||||
// ---- alloc/free: mmap-backed runtime allocator ----------------------
|
||||
//
|
||||
// Direct round-trip. Write-then-read-back proves the returned page is
|
||||
// dereferenceable. A miscompiled binding (wrong arg order, wrong ABI,
|
||||
// etc.) would either fault or return zero here.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// stattest — exercises [[os.stat]] / [[os.lstat]] / [[os.fstat]] /
|
||||
// [[os.exists]] against a scratch tree each row arranges itself
|
||||
// under [[temp.dir]] (Hare's own idiom: os tests self-arrange in a
|
||||
// temp dir), so the suite passes bare with no external driver:
|
||||
// Each row arranges its own scratch tree under [[temp.dir]] (Hare's
|
||||
// own idiom: os tests self-arrange in a temp dir), so the suite
|
||||
// passes bare with no external driver:
|
||||
//
|
||||
// <root>/regfile regular file, 11 bytes "hello world", 0644
|
||||
// <root>/symlink → ./regfile (relative symlink)
|
||||
@@ -66,14 +65,6 @@ fn istype(m: os.mode, t: os.mode) bool = {
|
||||
return ((m as u32) & 61440u32) == (t as u32);
|
||||
};
|
||||
|
||||
// ---- stat: regular file --------------------------------------------
|
||||
//
|
||||
// Pinned bytes are "hello world" (11 bytes). We verify:
|
||||
// - mask is fully set (newfstatat fills everything)
|
||||
// - mode's type bits == REG
|
||||
// - sz == 11
|
||||
// - inode is non-zero (real fs entry, not synthetic)
|
||||
|
||||
@test fn test_stat_regfile() void = {
|
||||
let t: tree;
|
||||
mktree(&t);
|
||||
@@ -112,8 +103,6 @@ fn istype(m: os.mode, t: os.mode) bool = {
|
||||
rmtree(&t);
|
||||
};
|
||||
|
||||
// ---- stat: directory ------------------------------------------------
|
||||
|
||||
@test fn test_stat_subdir() void = {
|
||||
let t: tree;
|
||||
mktree(&t);
|
||||
@@ -127,8 +116,6 @@ fn istype(m: os.mode, t: os.mode) bool = {
|
||||
rmtree(&t);
|
||||
};
|
||||
|
||||
// ---- stat: missing path → oserror ENOENT ---------------------------
|
||||
|
||||
@test fn test_stat_noent() void = {
|
||||
let t: tree;
|
||||
mktree(&t);
|
||||
@@ -143,11 +130,6 @@ fn istype(m: os.mode, t: os.mode) bool = {
|
||||
rmtree(&t);
|
||||
};
|
||||
|
||||
// ---- stat (follow) vs lstat (no-follow) on a symlink ----------------
|
||||
//
|
||||
// stat follows the link → reports the regfile (REG, 11 bytes).
|
||||
// lstat does NOT follow → reports the link itself (LINK).
|
||||
|
||||
@test fn test_stat_symlink_follow() void = {
|
||||
let t: tree;
|
||||
mktree(&t);
|
||||
@@ -175,8 +157,6 @@ fn istype(m: os.mode, t: os.mode) bool = {
|
||||
rmtree(&t);
|
||||
};
|
||||
|
||||
// ---- fstat: open a file and stat by fd ------------------------------
|
||||
|
||||
@test fn test_fstat_regfile() void = {
|
||||
let t: tree;
|
||||
mktree(&t);
|
||||
@@ -194,8 +174,6 @@ fn istype(m: os.mode, t: os.mode) bool = {
|
||||
rmtree(&t);
|
||||
};
|
||||
|
||||
// ---- exists: true on regfile/dir/symlink, false on noent ------------
|
||||
|
||||
@test fn test_exists_regfile() void = {
|
||||
let t: tree;
|
||||
mktree(&t);
|
||||
@@ -217,8 +195,6 @@ fn istype(m: os.mode, t: os.mode) bool = {
|
||||
rmtree(&t);
|
||||
};
|
||||
|
||||
// ---- ENAMETOOLONG: kpath rejects paths >= PATH_MAX -------------------
|
||||
//
|
||||
// kpath copies into a single [PATH_MAX]u8 buffer and reserves one byte
|
||||
// for the NUL terminator (`p.len + 1 >= PATH_MAX` → reject). The
|
||||
// rejection surfaces as `oserror = -36` (ENAMETOOLONG) on (... |
|
||||
|
||||
Reference in New Issue
Block a user