BBS: TELESC.NET.BR
Assunto: src/syncterm/Wren.adoc src/syncterm/scripts/console.wren syncterm.wren
De: Deuc¨
Data: Tue, 28 Apr 2026 04:20:01 -0700
-----------------------------------------------------------
https://gitlab.synchro.net/main/sbbs/-/commit/e2528de46b9d76fdceb6ea0d
Modified Files:
src/syncterm/Wren.adoc src/syncterm/scripts/console.wren syncterm.wren src/syncterm/term.c wren_bind.c wren_host.c wren_host.h wren_host_internal.h
Log Message:
SyncTERM: Wren API audit + Directory rework + doc completeness pass
Three threads, committed together because they overlap in the same files:
API shape audit
---------------
* Input.next, Input.poll, Input.nextEvent converted from getters
to methods (Input.next(), Input.poll(), Input.nextEvent()). The
rule "getters are for things that feel like variable access, not
things that feel like they're doing something" these block,
poll, or park a fiber, so they're actions.
* Directory.list converted from method to a foreign Map getter.
The directory's contents read like a property; indexing
`Cache.list["RIP"]` returns the File or Directory handle for that
name (or null), which composes naturally for tree traversal:
`Cache.list["RIP"].list["icons.dat"]`.
Directory rework
----------------
* Directory.create(name) now actually creates the file (was a
no-op File-object factory). Uses C11 exclusive-create
(fopen("wbx")) for race-free atomic creation. Returns null on
any failure (file exists, invalid name, path too long, OS reject).
* Directory.createDir(name) added. Mirrors create() for
subdirectories via MKDIR (which is naturally exclusive).
* Directory.delete(name) added. Parent-acts-on-child shape:
removes the named entry (regular file or empty directory only;
refuses symlinks, devices, FIFOs). Returns bool.
* File.delete() removed. The instance-method-that-zombies-its-
receiver shape was awkward; Directory.delete(name) covers the
case from the parent.
* Directory.list now returns Files AND Directories the C
implementation always built a Map keyed by name with File values
for regular files; this extends it to also emit Directory values
for subdirectories, matching the documented intent.
Live-handle registry
--------------------
A successful Directory.delete shouldn't leave outstanding handles
to the removed entry quietly operating on stale paths. Each
wren_file and wren_directory now self-registers on a doubly-linked
list rooted on wren_host_state. Helpers fs_register_*,
fs_unregister_*, fs_kill_*, fs_invalidate_subtree.
Two layers of staleness protection on every File / Directory
operation:
1. dead flag set by fs_invalidate_subtree when a parent's
delete removes the entry (or marks an ancestor). file_check /
dir_check (called at the top of every method) abort the fiber
on dead.
2. Per-call fexist() / isdir() catches deletions that bypassed
Directory.delete (other process, the user, another script).
On miss: fs_kill_*(handle) (mark dead + unregister) + throw.
Open-file exemption: a File between open() and close() skips
the fexist() check (its fd is authoritative Unix lets reads/
writes continue past unlink, and Windows refuses to delete
open files at all). fs_invalidate_subtree skips fp != NULL
entries on the same logic. fn_File_close re-runs fexist()
after fclose; if the path is gone, the handle becomes dead.
Wren.adoc completeness pass
---------------------------
Stale "see ciolib.h" references replaced with full reference
content:
* Codepage every entry described, _b suffix explained.
* Key full grouped tables (ASCII / cursor / modified Insert-
Delete / modified arrows / function keys with all four modifier
columns / synthetic markers).
* Font full 46-row table including the 1-31 unnamed-in-Wren
slots that are still reachable numerically; "thin"/"swiss"
font-style annotations explained.
* Screen.supports, Screen.videoFlags every flag described.
* ConnType, Emulation, BBSListType, ScreenMode, AddressFamily,
MusicMode, RipVersion, Parity, FlowControl, LogLevel, ExtAttr,
LastColumnFlag, LogMode, StatusDisplay all converted from
bare name lists to descriptive tables.
Corrections to wrong descriptions:
* sxScroll SIXEL scroll mode (not "smooth scroll" / DECSCLM).
* blinkAltChars repurposes attribute bit 7 to select the alt
character set (not "animate alt-char-set on blink interval").
* StatusDisplay VT320 DECSSDT semantics (host-writable status
line, not "verbose status showing connected host").
Worked example replaced. The "auto-respond to a prompt" example
was using onInput + manual line buffering with a logic bug that
only checked for prompts on LF (so "Logon: " which has no
trailing LF never matched). Replaced with a Hook.onMatch
two-liner; added a smaller per-byte BEL-counter example that
demonstrates onInput correctly without the broken pattern.
Anchors added: [[hook-events]], [[modal-input]], [[codepage]],
[[filename-policy]], [[directory-handle-staleness]] so the
existing <<...>> cross-refs resolve.
Co-Authored-By: Claude Opus 4.7 (1M context)
n
---
mSynchronetn hgVertrauen n hHome of Synchronet n gh[vert/cvs/bbs].synchro.net
-----------------------------------------------------------
[Voltar]