diff --git a/src/node_native_module.cc b/src/node_native_module.cc index b3a104547f392d..f788732ae569d4 100644 --- a/src/node_native_module.cc +++ b/src/node_native_module.cc @@ -205,33 +205,17 @@ MaybeLocal NativeModuleLoader::LoadBuiltinModuleSource(Isolate* isolate, #ifdef NODE_BUILTIN_MODULES_PATH std::string filename = OnDiskFileName(id); - uv_fs_t req; - uv_file file = - uv_fs_open(nullptr, &req, filename.c_str(), O_RDONLY, 0, nullptr); - CHECK_GE(req.result, 0); - uv_fs_req_cleanup(&req); - - auto defer_close = OnScopeLeave([file]() { - uv_fs_t close_req; - CHECK_EQ(0, uv_fs_close(nullptr, &close_req, file, nullptr)); - uv_fs_req_cleanup(&close_req); - }); - std::string contents; - char buffer[4096]; - uv_buf_t buf = uv_buf_init(buffer, sizeof(buffer)); - - while (true) { - const int r = - uv_fs_read(nullptr, &req, file, &buf, 1, contents.length(), nullptr); - CHECK_GE(req.result, 0); - uv_fs_req_cleanup(&req); - if (r <= 0) { - break; - } - contents.append(buf.base, r); + int r = ReadFileSync(&contents, filename.c_str()); + if (r != 0) { + const std::string buf = SPrintF("Cannot read local builtin. %s: %s \"%s\"", + uv_err_name(r), + uv_strerror(r), + filename); + Local message = OneByteString(isolate, buf.c_str()); + isolate->ThrowException(v8::Exception::Error(message)); + return MaybeLocal(); } - return String::NewFromUtf8( isolate, contents.c_str(), v8::NewStringType::kNormal, contents.length()); #else diff --git a/src/util.cc b/src/util.cc index 01e15acb0e5c09..40ea25b8d2edfe 100644 --- a/src/util.cc +++ b/src/util.cc @@ -221,6 +221,40 @@ int WriteFileSync(v8::Isolate* isolate, return WriteFileSync(path, buf); } +int ReadFileSync(std::string* result, const char* path) { + uv_fs_t req; + uv_file file = uv_fs_open(nullptr, &req, path, O_RDONLY, 0, nullptr); + if (req.result < 0) { + return req.result; + } + uv_fs_req_cleanup(&req); + + auto defer_close = OnScopeLeave([file]() { + uv_fs_t close_req; + CHECK_EQ(0, uv_fs_close(nullptr, &close_req, file, nullptr)); + uv_fs_req_cleanup(&close_req); + }); + + *result = std::string(""); + char buffer[4096]; + uv_buf_t buf = uv_buf_init(buffer, sizeof(buffer)); + + while (true) { + const int r = + uv_fs_read(nullptr, &req, file, &buf, 1, result->length(), nullptr); + if (req.result < 0) { + uv_fs_req_cleanup(&req); + return req.result; + } + uv_fs_req_cleanup(&req); + if (r <= 0) { + break; + } + result->append(buf.base, r); + } + return 0; +} + void DiagnosticFilename::LocalTime(TIME_TYPE* tm_struct) { #ifdef _WIN32 GetLocalTime(tm_struct); diff --git a/src/util.h b/src/util.h index 79ad3dfe2d071b..050e4bda35a139 100644 --- a/src/util.h +++ b/src/util.h @@ -813,6 +813,10 @@ std::unique_ptr static_unique_pointer_cast(std::unique_ptr&& ptr) { } #define MAYBE_FIELD_PTR(ptr, field) ptr == nullptr ? nullptr : &(ptr->field) + +// Returns a non-zero code if it fails to open or read the file, +// aborts if it fails to close the file. +int ReadFileSync(std::string* result, const char* path); } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS