Skip to content

Add fs.cpSync, fs.cp and fs/promises cp - #1166

Merged
ctate merged 3 commits into
mainfrom
ctate/add-fs-cpsync-b34458
Oct 17, 2026
Merged

ctate merged 3 commits into
mainfrom
ctate/add-fs-cpsync-b34458

Conversation

@ctate

@ctate ctate commented Oct 17, 2026

Copy link
Copy Markdown
Collaborator
  • Copy files, directories and symlinks with every option, following Node's synchronous and asynchronous implementations, including their different error shapes.
  • Add Node's SystemError (info, errno, syscall, path) and native-binding error shapes to the runtime.
  • fs/promises cp of 5 x 2,000 files: 184 ms against Node's 1,436 ms; cpSync matches Node (171 ms against 166 ms).

fs.cpSync, fs.cp and fs/promises cp compile with every option:
dereference, errorOnExist, filter, force, mode, preserveTimestamps,
recursive and verbatimSymlinks. They follow Node's two implementations.
cpSync follows cp-sync.js over the fs binding: copy errors are plain
Errors with a code, std::error_code failures throw an ErrnoException,
and links inside a copied directory point at their canonical targets.
fs.cp and fs/promises cp follow cp.js, whose copy errors are
SystemErrors with code, info, errno, syscall and path.

Options and paths validate in Node's order with Node's errors. filter
runs for the top-level paths and each entry in Node's order; an async
filter must return a promise that is already settled, and a pending one
throws SC2020. The callback and promise forms complete the copy before
the callback runs or the promise settles. Windows builds throw SC2020.

The copy lives in the new scr_fs_cp.c. Directory walks keep their frames
on the heap, so deep trees also copy on a fiber's stack. File contents
copy with sendfile on Linux, and COPYFILE_FICLONE uses FICLONE
where it exists. ScrError gains the SystemError context and the
ErrnoException key order, with matching fields in the compiler's Error
layout. The stored fs.cp callback uses the same implementation.

Corpus 5567-5571 cover the sync, callback and promise forms, errors,
symlinks and 1500-level trees.
@vercel

vercel Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
scriptc Ready Ready Preview, v0 Oct 17, 2026 7:31am UTC

std::filesystem::copy_file reports a destination that exists but is not
a regular file as invalid_argument in libstdc++ and as not_supported in
libc++, which Node's macOS builds use. cpSync on Apple platforms now
throws ENOTSUP there, as Node does, and the fs errno names include
ENOTSUP.

Corpus 5571 copies a 400-level directory chain instead of 1500 levels,
so its deepest path stays under macOS's 1024-byte PATH_MAX.
@ctate
ctate merged commit bf63243 into main Oct 17, 2026
75 checks passed
@ctate
ctate deleted the ctate/add-fs-cpsync-b34458 branch October 17, 2026 07:55

This branch was successfully deployed

1 active deployment
Preview — 5c398217 Deployed Oct 17, 2026 by vercel[bot]
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