diff --git a/ffi/libc.lua b/ffi/libc.lua index e22c5c5..d473315 100644 --- a/ffi/libc.lua +++ b/ffi/libc.lua @@ -1,18 +1,33 @@ --- ffi/libc.lua — shared libc bindings: errno, signal, write, read, chdir. +-- ffi/libc.lua — shared libc bindings: chdir, errno, strerror. +-- Phase 0: just enough to make `cd` interception work in executor.lua. +-- See docs/PHASE0.md §7. local ffi = require("ffi") ffi.cdef[[ int chdir(const char *path); -int errno; +int *__errno_location(void); char *strerror(int errnum); ]] +local C = ffi.C + local M = {} -- Apply chdir per PHASE0.md §7 (intercepts `cd` so wd persists across popen). +-- Returns: true on success; false, errmsg on failure. function M.chdir(path) - error("libc.chdir: not implemented (Phase 0 pending)") + local rc = C.chdir(path) + if rc == 0 then return true end + return false, ffi.string(C.strerror(C.__errno_location()[0])) +end + +function M.errno() + return C.__errno_location()[0] +end + +function M.strerror(en) + return ffi.string(C.strerror(en)) end return M