diff --git a/lib/fs.js b/lib/fs.js index 7087644674d..8eaba7984cc 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -995,7 +995,11 @@ fs.ftruncateSync = function(fd, len = 0) { validateUint32(fd, 'fd'); validateLen(len); len = Math.max(0, len); - return binding.ftruncate(fd, len); + const ctx = {}; + binding.ftruncate(fd, len, undefined, ctx); + if (ctx.errno !== undefined) { + throw new errors.uvException(ctx); + } }; fs.rmdir = function(path, callback) { diff --git a/src/node_file.cc b/src/node_file.cc index 073902ce7de..10149b403e2 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -711,18 +711,24 @@ static void Rename(const FunctionCallbackInfo& args) { static void FTruncate(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); + const int argc = args.Length(); + CHECK_GE(argc, 3); + CHECK(args[0]->IsInt32()); + const int fd = args[0].As()->Value(); + CHECK(args[1]->IsNumber()); + const int64_t len = args[1].As()->Value(); - int fd = args[0]->Int32Value(); - const int64_t len = args[1]->IntegerValue(); - - if (args[2]->IsObject()) { - CHECK_EQ(args.Length(), 3); + if (args[2]->IsObject()) { // ftruncate(fd, len, req) + CHECK_EQ(argc, 3); AsyncCall(env, args, "ftruncate", UTF8, AfterNoArgs, uv_fs_ftruncate, fd, len); - } else { - SYNC_CALL(ftruncate, 0, fd, len) + } else { // ftruncate(fd, len, undefined, ctx) + CHECK_EQ(argc, 4); + fs_req_wrap req_wrap; + SyncCall(env, args[3], &req_wrap, "ftruncate", + uv_fs_ftruncate, fd, len); } } diff --git a/test/parallel/test-fs-error-messages.js b/test/parallel/test-fs-error-messages.js index ef38652d7a3..b7e7ab6a2cc 100644 --- a/test/parallel/test-fs-error-messages.js +++ b/test/parallel/test-fs-error-messages.js @@ -455,3 +455,30 @@ function re(literals, ...values) { validateError ); } + +// ftruncate +{ + const validateError = (err) => { + assert.strictEqual(err.syscall, 'ftruncate'); + // Could be EBADF or EINVAL, depending on the platform + if (err.code === 'EBADF') { + assert.strictEqual(err.message, 'EBADF: bad file descriptor, ftruncate'); + assert.strictEqual(err.errno, uv.UV_EBADF); + } else { + assert.strictEqual(err.message, 'EINVAL: invalid argument, ftruncate'); + assert.strictEqual(err.errno, uv.UV_EINVAL); + assert.strictEqual(err.code, 'EINVAL'); + } + return true; + }; + + const fd = fs.openSync(existingFile, 'r'); + fs.closeSync(fd); + + fs.ftruncate(fd, 4, common.mustCall(validateError)); + + assert.throws( + () => fs.ftruncateSync(fd, 4), + validateError + ); +}