diff --git a/lib/fs.js b/lib/fs.js index 4a69ef9bc46c33..b200f8d4c412e7 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1163,7 +1163,13 @@ fs.readlinkSync = function(path, options) { handleError((path = getPathFromURL(path))); nullCheck(path); validatePath(path, 'oldPath'); - return binding.readlink(pathModule.toNamespacedPath(path), options.encoding); + const ctx = { path }; + const result = binding.readlink(pathModule.toNamespacedPath(path), + options.encoding, undefined, ctx); + if (ctx.errno !== undefined) { + throw new errors.uvException(ctx); + } + return result; }; function preprocessSymlinkDestination(path, type, linkPath) { @@ -1982,7 +1988,10 @@ fs.realpathSync = function realpathSync(p, options) { if (ctx.errno !== undefined) { throw new errors.uvException(ctx); } - linkTarget = binding.readlink(baseLong); + linkTarget = binding.readlink(baseLong, undefined, undefined, ctx); + if (ctx.errno !== undefined) { + throw new errors.uvException(ctx); + } } resolvedLink = pathModule.resolve(previous, linkTarget); diff --git a/src/node_file.cc b/src/node_file.cc index 0129d2d3f99ba1..e193b53c73861e 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -648,9 +648,8 @@ static void Link(const FunctionCallbackInfo& args) { static void ReadLink(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - const int argc = args.Length(); - - CHECK_GE(argc, 1); + int argc = args.Length(); + CHECK_GE(argc, 3); BufferValue path(env->isolate(), args[0]); CHECK_NE(*path, nullptr); @@ -658,12 +657,18 @@ static void ReadLink(const FunctionCallbackInfo& args) { const enum encoding encoding = ParseEncoding(env->isolate(), args[1], UTF8); if (args[2]->IsObject()) { // readlink(path, encoding, req) - CHECK_EQ(args.Length(), 3); + CHECK_EQ(argc, 3); AsyncCall(env, args, "readlink", encoding, AfterStringPtr, uv_fs_readlink, *path); - } else { - SYNC_CALL(readlink, *path, *path) - const char* link_path = static_cast(SYNC_REQ.ptr); + } else { // readlink(path, encoding, undefined, ctx) + CHECK_EQ(argc, 4); + fs_req_wrap req_wrap; + int err = SyncCall(env, args[3], &req_wrap, "readlink", + uv_fs_readlink, *path); + if (err) { + return; // syscall failed, no need to continue, error info is in ctx + } + const char* link_path = static_cast(req_wrap.req.ptr); Local error; MaybeLocal rc = StringBytes::Encode(env->isolate(), @@ -671,9 +676,11 @@ static void ReadLink(const FunctionCallbackInfo& args) { encoding, &error); if (rc.IsEmpty()) { - env->isolate()->ThrowException(error); + Local ctx = args[3].As(); + ctx->Set(env->context(), env->error_string(), error).FromJust(); return; } + args.GetReturnValue().Set(rc.ToLocalChecked()); } }