diff --git a/lib/fs.js b/lib/fs.js index 95c32b4b71a..2cafcefc53d 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1004,7 +1004,9 @@ fs.fchmodSync = function(fd, mode) { validateUint32(mode, 'mode'); if (mode < 0 || mode > 0o777) throw new errors.RangeError('ERR_OUT_OF_RANGE', 'mode'); - return binding.fchmod(fd, mode); + const ctx = {}; + binding.fchmod(fd, mode, undefined, ctx); + handleErrorFromBinding(ctx); }; if (constants.O_SYMLINK !== undefined) { diff --git a/src/node_file.cc b/src/node_file.cc index 837d5971c86..623da28e817 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -1493,18 +1493,24 @@ static void Chmod(const FunctionCallbackInfo& args) { static void FChmod(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - CHECK(args[0]->IsInt32()); - CHECK(args[1]->IsInt32()); + const int argc = args.Length(); + CHECK_GE(argc, 2); - int fd = args[0]->Int32Value(); - int mode = static_cast(args[1]->Int32Value()); + CHECK(args[0]->IsInt32()); + const int fd = args[0].As()->Value(); + + CHECK(args[1]->IsInt32()); + const int mode = args[1].As()->Value(); FSReqBase* req_wrap = GetReqWrap(env, args[2]); - if (req_wrap != nullptr) { + if (req_wrap != nullptr) { // fchmod(fd, mode, req) AsyncCall(env, req_wrap, args, "fchmod", UTF8, AfterNoArgs, uv_fs_fchmod, fd, mode); - } else { - SYNC_CALL(fchmod, 0, fd, mode); + } else { // fchmod(fd, mode, undefined, ctx) + CHECK_EQ(argc, 4); + fs_req_wrap req_wrap; + SyncCall(env, args[3], &req_wrap, "fchmod", + uv_fs_fchmod, fd, mode); } } diff --git a/test/parallel/test-fs-error-messages.js b/test/parallel/test-fs-error-messages.js index dc925069ba0..d14a5b8effc 100644 --- a/test/parallel/test-fs-error-messages.js +++ b/test/parallel/test-fs-error-messages.js @@ -729,3 +729,23 @@ if (!common.isAIX) { ); }); } + +// fchmod +{ + const validateError = (err) => { + assert.strictEqual(err.message, 'EBADF: bad file descriptor, fchmod'); + assert.strictEqual(err.errno, uv.UV_EBADF); + assert.strictEqual(err.code, 'EBADF'); + assert.strictEqual(err.syscall, 'fchmod'); + return true; + }; + + common.runWithInvalidFD((fd) => { + fs.fchmod(fd, 0o666, common.mustCall(validateError)); + + assert.throws( + () => fs.fchmodSync(fd, 0o666), + validateError + ); + }); +}