Skip to content

[POSIX] Keep directory streams usable when rewind fails - #1063

Open
brandonpayton wants to merge 1 commit into
mainfrom
posix/directory-iterator-lifecycle-qk044
Open

[POSIX] Keep directory streams usable when rewind fails#1063
brandonpayton wants to merge 1 commit into
mainfrom
posix/directory-iterator-lifecycle-qk044

Conversation

@brandonpayton

Copy link
Copy Markdown
Member

Why

Kandelo sometimes recreates a host directory iterator to move a directory stream back to the beginning. The legacy rewinddir path closed the live iterator before opening its replacement. If opening the replacement failed, the kernel still pointed at a handle that was already closed, so the caller could no longer continue reading from its previous position.

The directory-entry retry cache added in #1060 is cleaned up in every reachable production lifecycle path, but its failure edges were not directly tested. A later change could accidentally retain an entry after a failed close or replay an entry that belongs to an older use of the same numeric handle.

What changed

  • Open and validate a replacement directory iterator before retiring the live one.
  • Preserve the original iterator and position if opening fails.
  • If closing the original iterator fails, discard the unused replacement and keep the original stream authoritative.
  • Document that a PlatformIO directory handle is opaque and cannot identify two live iterators at once.
  • Add direct bridge tests for failed close cleanup, defensive numeric-handle reuse cleanup, and a name-buffer failure after metadata was already written.
  • Document the resulting rewinddir behavior in the POSIX status reference.

Platform contracts

This protects POSIX directory-stream state and the shared host bridge used by both Node.js and browsers. It does not change the Wasm ABI, package artifacts, or VFS image format.

A WeakMap is intentionally not used. Directory handles cross the Wasm boundary as numbers, while WeakMap requires object keys and garbage collection cannot own POSIX resource lifetime. A future ownership consolidation, if needed, should be a strongly owned directory-record registry or the planned machine-wide open-file-description table.

Validation

  • ./scripts/dev-shell.sh bash scripts/ci-run-test-suite.sh cargo-kernel — 1,246 passed.
  • Focused host/test/readdir-atomicity.test.ts Vitest run without unrelated guest-fixture setup — 5 passed.
  • ./scripts/dev-shell.sh bash -lc "cd host && npm run typecheck" — passed.
  • git diff --check — passed.

The standard full Vitest setup was not used as local evidence because this clean worktree has no current musl sysroot. Repository CI will build matching guest fixtures and run the complete host suite.

Open the replacement iterator before retiring the active stream, and keep the old state authoritative if opening or closing the replacement sequence fails.

Add direct host-bridge coverage for throwing close calls, numeric handle reuse, and partial Wasm marshalling so pending entries cannot leak or disappear across retries.
@github-actions

Copy link
Copy Markdown
Contributor

Phase B-1 matrix build status — pr-1063-staging

ABI v41. 6 built, 0 failed, 6 total.

Package Arch Status Sha
kandelo-sdk wasm32 built e2df6499
rootfs wasm32 built a0d29e15
shell wasm32 built 7a287cb2
lamp wasm32 built f7c8d643
node-vfs wasm32 built 92c72b70
wordpress wasm32 built 2373060b

Auto-generated; replaced on each push. Raw data in the publish-status workflow artifact.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant