Say a temporary is one in the entry, not in its name

Saving something that already exists writes a temporary, deletes the
original and gives the temporary its name, so that nothing is lost if the
writing fails. The temporary was told apart from a real file by being
called sbfs.part or sbfs.out - and those are legal names. Starting a save
deleted whatever answered to one as stale scratch, so saving anything at
all in a directory destroyed your own file of that name there, silently.

Flag bit 0x04 now says it. The property is not in the contents - the same
bytes become the finished file the instant the rename lands - so it belongs
in the entry, which is the thing the commit changes. sbfsCreateTempAt is
the door temporaries come in by, the commit writes the flags flat along
with the name, and cleanup wipes what it finds only if the entry says it is
ours. Anything else stops the save instead.

The bit is also the recovery. Both listings show an unfinished write rather
than sizing it, because the size in the entry is the room that was asked
for and not what was written: "<unfinished>" from dir, and a line from
SplitDisk saying the blocks are held and a rename brings the data back.
That was the gap in what the last commit documented - the data survived a
crash and nothing would show you where it was.

Four new agreement checks, three of which fail with the guards removed. The
fourth needed rebuilding first: both tests started on one disk, and the
first save ate the sbfs.part that was the second test's SOURCE, so the copy
failed for want of a file, never opened a stream, and passed while
reporting on nothing. A disk each. The fifth check forges the wreckage by
setting the flag on a finished file, since nothing here can crash a save
half way through.

No version bump: a committed file never carries the bit, so a disk this
writes is byte for byte the disk the old code wrote, which the whole-image
comparisons confirm. Only the wreckage differs, and older code reads that
as an ordinary file - which is what it did before.
This commit is contained in:
Anachronaut
2026-08-25 23:22:37 -04:00
parent d6cbbb5034
commit ce8fb721fe
6 changed files with 242 additions and 13 deletions
+21
View File
@@ -356,6 +356,19 @@ dirCheck:
MVQA
CALL printSpaces
; A save that stopped before it committed says so instead of saying a size, because the
; size it holds is the room it asked for rather than what was written into it. Asked
; first, since it is the one thing here that is not really a file yet.
;
; IT IS SHOWN RATHER THAN HIDDEN, and that is the whole of the recovery this format
; offers: the bytes are all there under that name, so seeing it is what lets somebody
; rename it back. Left off the listing it would be blocks nobody could account for.
SETD.0 SbfsFoundFlags
LDA.0
INIB 0x04
AND
BNQ dirUnfinished
; A directory says so instead of saying a size. It has no blocks, so the arithmetic
; below would call it a file of no bytes - which is a different thing that happens to
; look the same from here.
@@ -406,6 +419,12 @@ dirInBlocks:
CALL newLine
BRI dirStep
dirUnfinished:
SETD.0 UnfinishedText
CALL printString
CALL newLine
BRI dirStep
dirIsDirectory:
SETD.0 DirFolders
LDA.0
@@ -3312,6 +3331,8 @@ Farewell:
"halted"
DirectoryText:
"<dir>"
UnfinishedText:
"<unfinished>"
BlocksText:
" blocks"
NotDirectory: