diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-21 22:37:06 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | 5dcfade5f102256de787b2157b01293160780411 (patch) | |
| tree | 256416f7a82eacc06233d6a543a1fdfec390daab /src/fs-help.txt | |
| parent | 297e14cfc36e4613a8c1cb3b995597d0a9c2873b (diff) | |
| download | pardes-5dcfade5f102256de787b2157b01293160780411.tar.gz pardes-5dcfade5f102256de787b2157b01293160780411.zip | |
Make a pane by opening /pane/new, and a Plan 9 idiom pass
The Tcreate that replaced acme's /new was a step away from the idiom dressed
up as a step toward it. A pane is named by a server-assigned serial, so the
create ignored the client's name: `mkdir /pane/foo` succeeded and left you
/pane/12. A mkdir that does not make the directory you named is worse than the
read-with-side-effect it replaced, and it broke in the shell workflow that
motivated the change. `create` is out of the declared features, so Tcreate is
EPERM again; Tremove stays, since `rm` to close a pane is unambiguously right.
/pane/new is now opened, not created: the open makes the pane, the read of
that fid answers its serial, two reads agree, and closing it leaves the pane.
That is /net/tcp/clone's mechanism (kernel/network/ip/devip.c, in ipopen),
not acme's, and the difference is deliberate. acme allocates during the walk
and lands inside the new window, so /dev/new/body works in one step, and it
can afford to list `new` because a Plan 9 directory read carries every entry's
stat and nothing walks. A kernel or FUSE mount walks and stats each name a
listing gave it, so allocate-on-walk would make a pane per `ls -l`. Allocating
on open keeps `new` listed -- a stat is not an open -- at the cost of the
one-step new/body. `new` stays unreachable from an editor path, because that
resolution serves Look hover previews.
The idiom pass behind it, read out of the Plan 9 tree at
~/05-genizah/principia-softwarica rather than recalled:
Rerror carries a string, not an errno (man 5 error: `ename[s]`), and acme
names every refusal. The five refusals pardes shares with acme now say what
they mean; the generic sites keep their bare errno rather than invent strings
acme does not have. body and tag declare DMAPPEND, which they had always
behaved as (acme(4): "always appended; the file offset is ignored"), checked
first against Linux's fs/9p, which never maps the bit. excl stays unset
everywhere, because acme sets DMEXCL on nothing. Blocking reads, per-object
addr scope and the readable pane ctl were already right. Real stat sizes and
qid versions stay: acme reports length 0 and version 0 for everything, and
Linux clients need better.
One bug fell out of it. open reset the addr range, so `echo '#0,#5' >addr;
cat addr` answered `0 0` and `cp addr dot` copied zeros. acme(4) makes the
contract explicit -- "a regular expression may be evaluated by writing it to
addr and reading it back" -- and acme gets away with resetting on the 0-to-1
open only because its clients hold the fid across both. A shell cannot: that
is two opens. The register is cleared by truncating it now.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Diffstat (limited to 'src/fs-help.txt')
| -rw-r--r-- | src/fs-help.txt | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/src/fs-help.txt b/src/fs-help.txt index 1e5d64c2..3113590a 100644 --- a/src/fs-help.txt +++ b/src/fs-help.txt @@ -8,16 +8,16 @@ exec write a line: a middle click, an editor command word or a shell line log one line per editor event (new/del/rename/save <serial> <name>); reads wait screen rendered screen as JSON, frozen from open to close listeners the session's dial addresses -pane/ mkdir makes a pane, rmdir <serial> closes it +pane/new open it to make a pane; the read answers that pane's serial pane/<n>/ name body tag ctl addr dot limit data xdata sel dirty mark scroll - errors event look exec, and pty/ for terminals + errors event look exec, and pty/ for terminals; rmdir closes it os/ the host filesystem src/ the editor's own sources, only in a -Dembed-sources=true build Below, $m is the mount point (PARDES_MOUNT in a Tty9p shell; 9ns and 9p work too): cat $m/index which panes exist - mkdir $m/pane/x; n=$(awk 'END{print $1}' $m/index) make a pane, take its serial + n=$(cat $m/pane/new) make a pane, take its serial echo /etc/hosts:3 > $m/look; cat $m/look open a file, see the pane it went to printf 'text\n' > $m/pane/$n/body append to a pane (>| truncates first) cat $m/pane/$n/name; echo notes.txt > $m/pane/$n/name read, then rename @@ -31,8 +31,8 @@ Below, $m is the mount point (PARDES_MOUNT in a Tty9p shell; 9ns and 9p work too echo exec > $m/pane/$n/pty/ctl restart a shell; also winsize C R, sig INT Pitfalls, one each: - Only mkdir in pane/ makes a pane; ls, stat, find and every read create nothing. - Panes are named by the serial the editor gives them, not by the name mkdir asked for. + Each open of pane/new makes another pane; two reads of one fid name the same one. + Only that open creates: ls, stat, find and every other read leave the tree alone. rmdir closes a pane even when it is dirty; index and pane/<n>/dirty show the flag. addr, dot and limit read the same pair of offsets they take, so cp between them works. dirty, mark and scroll read "0" or "1" and take "0" or "1"; truncating limit lifts it. |
