-
-
Notifications
You must be signed in to change notification settings - Fork 34.6k
src: consolidate C++ ReadFileSync/WriteFileSync utilities #61662
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This patch moves `ReadFileSync` and `WriteFileSync` from `src/util.cc` to `src/node_file_utils.cc`, consolidates the implementation to reuse code, and adds a few more enhancements: For `ReadFileSync`: - Use fstat-based pre-allocation to minimize buffer resizing and repeated reads for bigger files. - Handle various potential overflows in size conversions. - Handle fallback for 0-byte special files. For `WriteFileSync`: - Handle potential partial writes for big enough files and support non-seekable files (with -1 as offset). - Handle 0-byte writes correctly. In both cases, this now avoids hard aborts and return error code for the caller to handle as much as possible, except `std::vector<char> ReadFileSync(FILE* fp)` which is part of the embedder API. This patch uses the new `ReadFileSync` to address a TODO in node_sea.bin.cc.
|
Review requested:
|
|
cc @nodejs/cpp-reviewers |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #61662 +/- ##
==========================================
- Coverage 89.74% 89.73% -0.02%
==========================================
Files 674 675 +1
Lines 204348 204444 +96
Branches 39271 39288 +17
==========================================
+ Hits 183396 183452 +56
- Misses 13262 13280 +18
- Partials 7690 7712 +22
🚀 New features to boost your workflow:
|
Qard
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. A few small code quality improvement ideas, but I'm fine landing as-is. These are just minor suggestions to simplify things slightly. 🙂
| while (idx < iovs.size() && iovs[idx].len == 0) { | ||
| idx++; | ||
| } | ||
| if (idx >= iovs.size()) { // No non-empty buffers left. | ||
| break; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took me a moment to understand the connection between these and the outer loop. Perhaps a clearer version might simply be:
| while (idx < iovs.size() && iovs[idx].len == 0) { | |
| idx++; | |
| } | |
| if (idx >= iovs.size()) { // No non-empty buffers left. | |
| break; | |
| } | |
| if (iovs[idx].len == 0) { | |
| idx++; | |
| continue; | |
| } |
| if (req.result < 0) { // Error during write. | ||
| int err = req.result; | ||
| uv_fs_req_cleanup(&req); | ||
| uv_fs_close(nullptr, &req, fd, nullptr); | ||
| uv_fs_req_cleanup(&req); | ||
| return err; | ||
| } | ||
| if (req.result == 0) { // Should not happen unless the file system is full. | ||
| uv_fs_req_cleanup(&req); | ||
| uv_fs_close(nullptr, &req, fd, nullptr); | ||
| uv_fs_req_cleanup(&req); | ||
| return UV_EIO; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could merge those to:
| if (req.result < 0) { // Error during write. | |
| int err = req.result; | |
| uv_fs_req_cleanup(&req); | |
| uv_fs_close(nullptr, &req, fd, nullptr); | |
| uv_fs_req_cleanup(&req); | |
| return err; | |
| } | |
| if (req.result == 0) { // Should not happen unless the file system is full. | |
| uv_fs_req_cleanup(&req); | |
| uv_fs_close(nullptr, &req, fd, nullptr); | |
| uv_fs_req_cleanup(&req); | |
| return UV_EIO; | |
| } | |
| if (req.result <= 0) { // Error during write. | |
| // UV_EIO should not happen unless the file system is full. | |
| int err = req.result < 0 ? req.result : UV_EIO; | |
| uv_fs_req_cleanup(&req); | |
| uv_fs_close(nullptr, &req, fd, nullptr); | |
| uv_fs_req_cleanup(&req); | |
| return err; | |
| } |
This patch moves
ReadFileSyncandWriteFileSyncfromsrc/util.cctosrc/node_file_utils.cc, consolidates the implementation to reuse code, and adds a few more enhancements:For
ReadFileSync:For
WriteFileSync:In both cases, this now avoids hard aborts and return error code for the caller to handle as much as possible, except
std::vector<char> ReadFileSync(FILE* fp)which is part of the embedder API.This patch uses the new
ReadFileSyncto address a TODO in node_sea.bin.cc.Some numbers from
--build-sea(note that most of the time is spent on parsing the executable and building the SEA, but even so there's a measurable difference just from the file I/O because the binary is ~120MB).