Skip to content

feat(fs): long-tail ops — fsync/fdatasync, f*/l* metadata, readv/writev, statfs, glob (#976)#1006

Merged
nickna merged 1 commit into
wrk/issue-972-filehandlefrom
wrk/issue-976-fs-longtail
Jun 29, 2026
Merged

feat(fs): long-tail ops — fsync/fdatasync, f*/l* metadata, readv/writev, statfs, glob (#976)#1006
nickna merged 1 commit into
wrk/issue-972-filehandlefrom
wrk/issue-976-fs-longtail

Conversation

@nickna

@nickna nickna commented Jun 29, 2026

Copy link
Copy Markdown
Owner

Closes #976 (part of epic #968). Stacked on #1005 (#972) — merge that first.

Completes the fs long tail across sync/callback/promise in both modes:

  • Durability: fsync/fdatasync (+Sync)
  • fd-variant metadata: fchmod/fchown/futimes (+Sync, routed through a new fdPath primitive)
  • symlink metadata: lchmod (→ENOSYS), lutimes (+Sync)
  • vectored I/O: readv/writev (+Sync)
  • statfs/statfsSync/promises.statfs (+{bigint})
  • minimal glob/globSync/promises.glob (*/?/** matcher; promise form is an async iterator)
  • exists (deprecated)

Only 3 genuinely-native ops needed new dual-mode primitives (fsyncSync, fdPath, statfsRaw) — interp + BCL-only emitted IL (RuntimeEmitter.FsLongTail.cs), standalone preserved. Everything else is one shared facade TS impl. FileHandle.sync/datasync upgraded to a real fd flush.

Deferred (issue-optional): realpathSync.native, openAsBlob.

Tests: 5 dual-mode (10 cases). Full suite 14472/0; TS conformance unchanged.

…ev, statfs, glob (#976)

Completes the fs long tail across sync/callback/promise in both modes (epic #968):

- Durability: fsync/fsyncSync, fdatasync/fdatasyncSync.
- fd-variant metadata: fchmod/fchown/futimes (routed through a new fdPath
  primitive to the path ops) + Sync forms.
- symlink metadata: lchmod (BSD/macOS-only -> ENOSYS elsewhere), lutimes.
- vectored I/O: readv/writev + Sync forms (loops over read/writeSync).
- statfs/statfsSync/promises.statfs (+ {bigint}), from DriveInfo.
- a minimal glob/globSync/promises.glob: `*`/`?`/`**` matcher over a recursive
  readdir walk; the promise form is an async iterator (Node 22+).
- exists (deprecated, non-err-first callback).

Approach B: only the genuinely native ops need primitives — fsyncSync, fdPath,
and statfsRaw — added in interp (FsModuleInterpreter) and as BCL-only emitted IL
(RuntimeEmitter.FsLongTail.cs) so compiled output stays standalone. Everything
else is one TS implementation in fs.ts/fs/promises.ts shared by both modes.
FileHandle.sync/datasync now do a real fd flush.

Deferred (issue-optional): realpathSync.native (function-property expando is
unsafe in compiled mode) and openAsBlob (needs Blob).

Gotcha: __globWalk's `catch { return }` tripped the compiled InvalidProgramException
(the #973 return-in-catch pattern); restructured to an assignment-only catch.

Verified byte-identical interp==compiled (scratch smoke), standalone preserved,
5 dual-mode tests per family (10 cases). Full suite 14472/0; TS conformance unchanged.
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