| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
stays open: another client's command in the same directory gets a pane of its own
A finished command pane was the next command's for its directory, from
any client, so with four clients scripting one session, one read
another's output as its own last run. An open of a look or exec file
whose write was answered a pane's serial now holds that pane: reuse
passes over it and a new command pane runs the line. The open's own
next command may run there again, and once it is closed the directory's
one command pane is reused as before.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
another client's exec meanwhile can never take the text into its pane
pardes - wrote `pager <dir>` to /ctl, then read /exec on a fresh open,
which answers the session's last answer: a client that exec'd in
between had its pane overwritten by the paged text. /pager takes the
directory and answers the +Pager's serial on the open that wrote it,
as /pane/new answers its own open; the ctl verb is gone. Client.ask
writes and reads on one open. The README's look recipe reads its
answer on its own open too.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
cat sel reads it back; one open's writes run on from the last
The selection collapsed to a point after the write, so sel read back
nothing. What is written is now dot, and the next write of the same
open goes at its end and grows it (acme's wrselrange), so a shell's
several writes make one selection; another open's write replaces it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
A script following a pane's event in a loop ended in an error when the
pane went, though nothing had gone wrong: the pane was simply done. A
read on an event open whose pane has closed now answers no bytes, the
end a pipe's reader sees when its writer goes, so cat and while-read
end cleanly. pty/data keeps acme's answer.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
and nonseekable: fs.md's follow recipe with cat works through a mount
The log stated the length an open would freeze, a length a mount's
kernel could take as its end, and a splicing cat read it from the
kernel's offset. log now stats 0, as the other streams and generated
views do, and the re-pinned cloud9's 9ns opens any file stating 0
FOPEN_DIRECT_IO | FOPEN_NONSEEKABLE. A look at such a file (the mounted
index) reads a regular file that will not seek as a stream rather than
refusing it as a pipe. selfmount runs the recipe, exec 3<>log; echo
follow >&3; cat <&3, through the mount and hears a record made after it
started.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
not UTF-8 included, so what name reads writes back as it was
A pane opened on a file whose name held a tab, a control byte or bytes
not UTF-8 read that name from its name file, and the same bytes written
back were refused. Only what no file name holds is refused now: a second
line and a NUL. The ctl word name still refuses a second blank after the
word, as a line's words are split at blanks.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
layout, recent and listeners; fs.md says which files have real lengths
A stat of index, layout, recent or listeners built the whole view to
count it, and data and xdata reported the body's length though a read
answers what addr selects. Those now stat 0, as screen and pane/new
already did, and fs.md lists the files whose length is real and says to
read the rest to the end.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
truncation waits for the write, as limit's does
echo /nomatch/ > dot truncated dot to an empty range at the top before
the write was refused, so a failed address still moved the selection
and scrolled. The truncation is now held until the write that follows
it: that write sets dot, or, refused, leaves it as it was. A truncation
with no write after it (: > dot) empties it when its open goes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
not permitted, EPERM, not an EIO
cloud9's engine passes a wstat that changes a name to the backend, and
the tree's setattr ignored the name: the rename answered as done, the
name did not change, and a mount then gave `mv` EIO. The tree names its
own files, so a setattr with a name is now refused, "rename not
permitted", which 9ns reads as EPERM. A pane's buffer is still renamed
through its name file.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
spends no column serial
A pane/new, look or exec refused ENOSPC made its pane before placing it.
The refusal closed the pane unannounced, but its serial was gone, so the
next pane skipped one. When sync removes a refused pane that holds the
newest serial, it now puts the counter back.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
one that fills its Twrite does: a burst through a mount no longer runs its cut lines as two commands
selfmount's 1000-line burst reported 943 lines, on main too. The log
ring was not losing records: a follower opened before the burst heard
exactly 943 and no `lost`, and the burst itself exited 1 with
`err 1 exec: wrong #args in control message "Msg"`. `seq ... > exec`
through the mount arrives as stdio's 4096-byte writes, each shorter than
a Twrite. The rule that such a write is whole ran each one's cut last
line at once, so both halves of the line ran as commands (hence `exit
127` records). At 12288 bytes the cut left a bare `Msg`, which was
refused and failed the write and the rest of the burst.
A write of a multiple of 4096 bytes is where a writer's buffer (stdio, a
page cache) filled, so it may go on: its unended tail now waits for the
next write or the close, like one that fills its Twrite. `printf Save >
exec` stays whole at once. fs.md says so, the 9P fuzzer's model of served
lines follows it, and a unit test cuts a `Msg` at 4096 bytes.
A follower does not lose records silently: a ring that outruns one
already reads it `lost N` first (documented, tested). selfmount now
follows the log from before the burst, so it checks every line heard
once, in order, or a loss said, not a fresh open of a 64 KiB ring. It
passed 3 in 3 and joins the gates with the new 9ns.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
pane's does
A pane tag read back its text alone, but a column tag and /tag appended a
newline and gave a stat size one byte longer. So `$(cat tag)` agreed across
the three kinds while `cat tag | wc -c` and a byte compare did not. All
three now read the text alone, and fs.md says so.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
carries the session directory, not / and a rename
A pane named in the update that made it (Config's init file, a look
renamed on open) logged `rename N <name>` before `new N`, so a follower met
a serial it had never seen. The boot shell, started with no directory, was
announced as `new 1 /` and renamed once its shell spoke. Now noteLog drops
the rename of a pane not yet announced, since its new carries the name, and
announces a pane first for any other record about it. A terminal whose shell
has not said where it is is named by the session's directory, where it was
started, and the shell saying so is no rename.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
a refused line is quoted with its control bytes shown as blanks
fs.md already promised that the whole of a write to /ctl, a pane's ctl and
a column's ctl is checked first, as it is for exec and look. But a ctl write
ran its lines one by one, so a line holding a control byte gave that line's
own, misleading reason ("unknown command"). Worse, the reason quoted the raw
byte back into the err record. The check now happens in tree.write before
anything runs, with the same EINVAL and reason exec gives. A refusal's quoted
line shows control bytes as blanks, so an err record never carries a raw
escape.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
`>` write leaves the tag as it was
A column's or the workspace's tag took any length, so a write past 4096 bytes went in and a later Dump failed on it (bad dump tag), and a truncating open wiped any tag before the write after it could be refused. The column and workspace tags now refuse what a pane tag refuses: the 4096-byte limit (ENOSPC, tag: no space: over 4096 bytes) as well as the control characters they already did. A truncation of any of the three is held until the write after it is known to fit, and done with it; a refused write drops it; a close or read with no write after it does it then (so `: > tag` still clears). A test runs a truncating write too long, a control character and a bare truncation at each kind, and Dumps after. docs/fs.md says so.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |\ \ \
| | | |
| | | |
| | | | |
+ tty ssh acked frames
|
| | |/ /
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
pane under its tag and two rows, or is refused
A seeded sweep of placements (New, pane/new, Edit =, Tty, look, Delcol, deletes, refusals included) over screens 6 to 40 rows high found no refused placement that leaves a pane short since lyltlqnz and lrpzwyom; the pane a row short came from Newcol, which halves a column's width so long tags wrap onto more rows, raising those panes' minimums with no rows moved. Newcol now shares each such column's rows out again, and where a column has not the rows for every minimum there is no new column (Newcol: no space for a column: the panes' tags would not fit), as a size too small is refused. The sweep, 300 seeds, is the test; a user's drag or a tag grown by editing may still take a pane under, as before.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |/ /
| |
| |
| |
| |
| |
| |
| | |
middle to …
An Rerror carries 128 bytes (Plan 9's ERRMAX) and the engine cut longer text there, and a builtin's failure was first clipped between words to 256 with ...: either way the end, which says why, was what went. tree.handle now fits a long reason by cutting the middle of its longest path, else of the whole text, on a character boundary, and reportFailure fills its buffer the same way.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
a write to pane/new, is its error alone, and every refusal is said in words
The one-failure rule is a write's. A refused remove, pane/new's open refused for want of a slot, and an OTRUNC open's refused truncation (data's after a failed addr) also logged an err, and a reply carrying only an errno reached the client as the C library's text (Operation not permitted). tree.handle now gives such a reply Plan 9's words, chosen so 9ns maps each back to its errno (EPERM's to EACCES, as Plan 9's does), and serveFs logs errs for writes only, not a write to pane/new, which is only read. docs/fs.md and the 9P skill say so, and that a look miss quotes what was written.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
now say, not at the close
Round 24's no-newline rule (uwzuqzxp) already covers name, a lines file; the 9P monkey's close_runs_only_line_files repros were from a binary before it. This pins it with a test and corrects docs/fs.md, which still said such a name waited for the close.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| | |
is linear
Each body or data write copied and hashed the whole buffer, so a write the mount cut in 8 KB pieces was quadratic: 10 MB took 50 s and a 1 MB insert into 10 MB 11 s, holding the editor's turn. An open's appends to body, or inserts going on at data's address, are now held and put in as one splice (one copy, one undo step, one line-starts pass) before any other request, the close, or the editor's step once the writes pause 20 ms. fs.py-driven: 2 MB 2.19 -> 0.16 s, 10 MB 50.17 -> 0.78 s, 1 MB data into 10 MB 11.49 -> 0.26 s. A body-2m case (2 MB in 256 KB writes on one open) joins the perf gate: 84023 -> 15785 us; baselines re-recorded.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |/
|
|
|
|
|
|
| |
it needs more
A last line with no newline was held to the close, so printf bogus > ctl answered 0 and failed only in the log, Edit ,s/zzz/y/ too. A write shorter than its Twrite is the whole of what was written (acme takes each write whole): its tail runs then and a failure is the write's. It is held only when the parser says it needs more -- an open { block, an a/c/i text -- or when the write filled its Twrite and may go on (the listener tells the core the room, msize less its header).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
is a real refusal or says why it cannot fire
A sweep for round 23's crash: a run's answer (pty/run) was bufPrint'd into 48 bytes with catch unreachable, so a foreground program's long name (macOS gives up to 32 bytes) panicked; it now cuts at the room, keeping its newline, in 96 bytes. The rest were numbers into buffers sized for them, a braille codepoint, pthread calls on the queue's own mutex, and pdf_view's resolved outline entries: each now carries a one-line comment saying why it cannot fire.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
open
bash writes printf 'a\nb\n' a line at a time, so each line arrived as a whole name on the held open and renamed the pane twice. An open that has named its pane now refuses a further line, as a two-line write already was.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
moments
/index and the other listings were rendered afresh for each read, so a client reading one in chunks while panes changed got rows from two moments spliced together (the fs-test flake). /index, /layout, /recent, /commands, /status, /listeners and a ctl opened only to read now freeze at the open, as /screen does.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
The join mark a write left was the pane's, so another open's write joined the first open's step. Writing opens of body, data and xdata now get an open record, the mark names the open that set it, and another open's write starts its own step (the pane's one history: each turn the opens take is a step).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
Each write to name was taken as a whole name, so a name a client wrote in two pieces renamed the pane twice, the first time to half a name. name's writes are now held per open, as exec's and ctl's lines are, until the newline or the close.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
| |
bash line-buffers its stdout, so printf 'x\ny\nz\n' > data arrives as three writes and took three Undos. A write now leaves the join mark a truncation already left, so the next write on the file joins its step until the open is released; a truncation and any other edit start a step of their own.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
closed file reopens it
A file closed by accident, its path forgotten, could not be found again:
the jumplist dropped closed panes. Every file opened (a look, a Save of a
scratch, a Restore, a rename) goes first in a list of 200, kept once, its
dot noted when it closes, kept across sessions in $XDG_STATE_HOME/pardes/
recent. `Recent` (SPC f r) shows it in a reused +Recent, each row
`path:line:col open|closed` a look reopens; /recent reads `open|closed
<path>`. The jumplist keeps a closed file's entries, +Jumps marks them
`(closed)`, and Back to one opens the file at its place. acme has no
such thing; its dump and Load are the nearest.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
| |
A refused look logged `err N look: look: no space for a pane...`: the
reason began with the file's name, and the record put it before it again.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
name as \n
/index printed a name as it was, so a directory with a newline in it split
its row in two, and bytes not UTF-8 went through; the log turned the
newline into a space, silently another name. Both now show a name one
way: a newline `\n`, other controls, DEL and C1 a space, bytes not UTF-8
`\xNN`.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
character
An empty name, a word written to log other than follow, a data, sel, dot
or dirty write to a pane with no text, a truncate other than to zero,
and a control character in a look line written through a held open were
refused with no words, logged as `Invalid argument`. Each says its reason
now; and DEL is refused in exec and look lines as in names.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
A failure said while it ran (Exit's refusal, a Del refused) or later by
the host (a Save's write, a Dump's) left `msg N Save` in the log as if it
had worked. The announcement's record is remembered and taken back out
on either, unless a follower read it already. A refused pane/new logs its
err alone, and a failed Dump says its reason in words (`file not found`,
not `FileNotFound`) so its msg goes and the err is the one record.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
active pane's
No pane asked for it, so borrowing the directory of whichever pane last
had the keyboard named it after an accident; acme's new window has acme's
directory.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
A pane from pane/new or New takes the bottom half of its column's last
pane, as acme's coladd does (cols.c:62-65); when that pane is too short
to give it a tag and 2 rows, the fallback halved the tallest pane and
put the new one under it, mid-column (the 7 9 8 found). It now goes last
all the same, with half the tallest pane's rows (its tag measured at the
column's width). Tty from a pane's ctl already follows acme's
makenewwindow (the active column first, util.c:456-467); fs.md now says
so rather than beside that pane.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
An exec write does not fail for what its command says, so an a/c/i text
or { group cut short by a write that ended early was only a msg, easy to
miss. Over 9P, that failure (a truncated write, not a command's) is now
logged as an err record naming exec; the pane still says it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
sam takes the end of input as a text block's end, so a block cut short (a
write that lost its tail, an open closed early) inserted half of itself.
An Edit whose a, c or i text never meets its . line now fails with "a, c
or i text not ended by a . line" and changes nothing, as an unclosed {
does; at a close, logged as an err.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
The workspace had /tagexec and a column its exec, but a pane's own tag
could be clicked only by an event record. pane/<n>/tagexec runs each line
as a click in that pane's tag (never redirected to its event reader, as a
header's is not) and reads back what it touched. The README, fs.md and
the skill list it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
byte columns
Round 11's doc findings: the skill names the full-column refusal beside the
64-pane cap; fs.md and the skill say an Edit block still open when its open
closes fails with unmatched { and an err; and line:col's byte columns get
the tip for character columns from tools (the same on ASCII, else a
search or #n). A unit test pins the unmatched { at close.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Placement could split a pane down to a tag and one row, or give a new one
less. Every placement now checks the pane it made and each pane it shrank
against its tag (wrapped at its width) plus two rows: where they lack the
room, the column's tallest pane is halved instead, and where none can give
it the new pane is refused with "no space for a pane in that column"
(ENOSPC over 9P) and closed at the step's end, once its maker is done with
it. splitBelow and splitParent leave two body rows (a boot layout, split
before any row exists, is as before). Re-recorded by name: lookpanes (panes
one or two rows lower) and splitparent (the 6-row squeeze now refuses);
fs.py closes the scratches and long-named panes it no longer needs, since
its 24-row session filled.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
9ns reads an error's words, not its errno: "window shut down" came out as
EIO where every other file of a gone pane gives ENOENT, and "no pane
slots" as EIO. The event and pty/data reads a pane closed under now say
"no such pane: its window shut" (ENOENT), and the cap says "no space for
a pane: 64 max" (ENOSPC; 9ns has no word for ENFILE).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
A shell's > truncates limit, which lifted it, before the write; a write
that then failed left no limit at all. The truncation now keeps the old
limit until that open's write, and a failed write puts it back; a bare
truncation still lifts it once its open is released.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A mount cuts a write at its message size, and each piece ran on its own: a
line cut at the boundary ran as shell commands and a 50 KB Edit block
broke. An open of look, exec, tagexec, any ctl or a column's exec now keeps
an unfinished last line, or an Edit block still open, until its next write
or its release, and never runs a fragment. The same open record holds what
its last write touched, which a read on it answers (as /net/tcp/clone
does); an open that never wrote reads the session's last as of its open.
A release that runs a held line waits for quiet and counts as a change;
a clicked line with a control character is still refused at its write.
Tested in unit tests, fs.py (python client, 8 KiB) and selfmount.py (the
kernel mount, a 1000-line seq burst and a 50 KB Edit block).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
and a tag's words log as the session's
/tagexec runs a word as a click in the workspace tag, as col/<serial>/exec
does in a column's. A column's exec was write-only; it and /tagexec now
read back the serials the last write touched, as /exec does. A click in a
tag no longer goes to the focused pane's event reader, and what a word
run from a column's ctl or exec or /tagexec says is logged msg -, not
against the focused pane. The README, fs.md and the skill say so, and
document the answer record.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
A script could read and write a column's tag but not act on the column.
col/<serial>/ctl takes Delcol, Joincol, New and Tty, each acting on that
column as from its tag; col/<serial>/exec runs a word as a middle click in
the tag; rmdir col/<serial> closes an empty column and refuses one with
panes (ENOTEMPTY, an err record saying why). The root ctl's refusal of
Delcol and Joincol points at col/<serial>/ctl. A dump keeps each column's
serial and Restore logs restoredcol <old> <new>; the dump golden gains
them. Documented: Joincol's survivor, the column on the right, keeps its
serial and tag.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Sixteen panes was far too few for a real session. MAX_PANES is now 64 on a
desktop and stays 16 on the board; the 48 more slots cost about 3.7 KB each
in fixed tables (the core 1.33 to 1.45 MB, its surface 19 to 72 KB), and a
pane itself (84 KB and its terminal) is allocated only when it opens. At the
cap, pane/new fails with `pane/new: no pane slots: 64 max` and an err
record rather than a bare ENFILE, a 9P look or exec that would open a pane
fails its write with the same words and reads back empty, and New, Tty,
Tutor and Alt-n say it on the message row (their ctl writes fail with it).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
/col/<n> named a column by its index, which shifts when a column left of it
closes: exactly what scripts trip on. A column is now /col/<serial>, its
serial kept while it lives and never reused; /layout lines give serial and
index (`<serial> <index> ...`), active names the serial, /index's last
field is the column's serial, and the log says newcol and delcol with
serials. Docs, the skill and the tree's README say so.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
A script could not see where the panes sit or edit the tags a person
clicks in. /layout lists each column, its index, x and width in cells,
current or not, empty or full, and its panes' serials, then the active
column; /tag is the workspace tag and /col/<n>/tag a column's, read and
written as a pane tag is (one line: a newline written in is a space, and a
truncating write drops the one ending it); /index's lines end with the
pane's column; the log says newcol <n> and delcol <n>. acme serves no
column files, and the docs say so.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
takes no name
`echo Del > pane/6/exec` just after pane 6 closed failed EACCES: the shell's
lookup failed, it tried to create the file, and the engine refused every
Tcreate as a permission error. pardes now takes Tcreate itself: refused as
before (acme's fsyscreate refuses it too), ENOENT in a pane that has
closed. Renaming a terminal was refused with only EPERM; it now says a
terminal is named by its shell's directory, worded so a mount still maps
it to EPERM.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
`echo X > tag` stored X and a trailing newline, which drew an empty tag row.
After a truncation the newline ending each write is held back until more
text follows or the open is released, so the one ending the whole of it is
dropped and any other stays; `>>` keeps what it is given.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|