1// Flags: --expose-internals 2// Copyright Joyent, Inc. and other Node contributors. 3// 4// Permission is hereby granted, free of charge, to any person obtaining a 5// copy of this software and associated documentation files (the 6// "Software"), to deal in the Software without restriction, including 7// without limitation the rights to use, copy, modify, merge, publish, 8// distribute, sublicense, and/or sell copies of the Software, and to permit 9// persons to whom the Software is furnished to do so, subject to the 10// following conditions: 11// 12// The above copyright notice and this permission notice shall be included 13// in all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 16// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 18// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 19// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21// USE OR OTHER DEALINGS IN THE SOFTWARE. 22 23'use strict'; 24const common = require('../common'); 25const fixtures = require('../common/fixtures'); 26const tmpdir = require('../common/tmpdir'); 27const assert = require('assert'); 28const fs = require('fs'); 29const path = require('path'); 30 31tmpdir.refresh(); 32 33 34const nonexistentFile = path.join(tmpdir.path, 'non-existent'); 35const nonexistentDir = path.join(tmpdir.path, 'non-existent', 'foo', 'bar'); 36const existingFile = path.join(tmpdir.path, 'existingFile.js'); 37const existingFile2 = path.join(tmpdir.path, 'existingFile2.js'); 38const existingDir = path.join(tmpdir.path, 'dir'); 39const existingDir2 = fixtures.path('keys'); 40fs.mkdirSync(existingDir); 41fs.writeFileSync(existingFile, 'test', 'utf-8'); 42fs.writeFileSync(existingFile2, 'test', 'utf-8'); 43 44 45const { COPYFILE_EXCL } = fs.constants; 46const { internalBinding } = require('internal/test/binding'); 47const { 48 UV_EBADF, 49 UV_EEXIST, 50 UV_EINVAL, 51 UV_ENOENT, 52 UV_ENOTDIR, 53 UV_ENOTEMPTY, 54 UV_EPERM 55} = internalBinding('uv'); 56 57// Template tag function for escaping special characters in strings so that: 58// new RegExp(re`${str}`).test(str) === true 59function re(literals, ...values) { 60 const escapeRE = /[\\^$.*+?()[\]{}|=!<>:-]/g; 61 let result = literals[0].replace(escapeRE, '\\$&'); 62 for (const [i, value] of values.entries()) { 63 result += value.replace(escapeRE, '\\$&'); 64 result += literals[i + 1].replace(escapeRE, '\\$&'); 65 } 66 return result; 67} 68 69// stat 70{ 71 const validateError = (err) => { 72 assert.strictEqual(nonexistentFile, err.path); 73 assert.strictEqual( 74 err.message, 75 `ENOENT: no such file or directory, stat '${nonexistentFile}'`); 76 assert.strictEqual(err.errno, UV_ENOENT); 77 assert.strictEqual(err.code, 'ENOENT'); 78 assert.strictEqual(err.syscall, 'stat'); 79 return true; 80 }; 81 82 fs.stat(nonexistentFile, common.mustCall(validateError)); 83 84 assert.throws( 85 () => fs.statSync(nonexistentFile), 86 validateError 87 ); 88} 89 90// lstat 91{ 92 const validateError = (err) => { 93 assert.strictEqual(nonexistentFile, err.path); 94 assert.strictEqual( 95 err.message, 96 `ENOENT: no such file or directory, lstat '${nonexistentFile}'`); 97 assert.strictEqual(err.errno, UV_ENOENT); 98 assert.strictEqual(err.code, 'ENOENT'); 99 assert.strictEqual(err.syscall, 'lstat'); 100 return true; 101 }; 102 103 fs.lstat(nonexistentFile, common.mustCall(validateError)); 104 assert.throws( 105 () => fs.lstatSync(nonexistentFile), 106 validateError 107 ); 108} 109 110// fstat 111{ 112 const validateError = (err) => { 113 assert.strictEqual(err.message, 'EBADF: bad file descriptor, fstat'); 114 assert.strictEqual(err.errno, UV_EBADF); 115 assert.strictEqual(err.code, 'EBADF'); 116 assert.strictEqual(err.syscall, 'fstat'); 117 return true; 118 }; 119 120 common.runWithInvalidFD((fd) => { 121 fs.fstat(fd, common.mustCall(validateError)); 122 123 assert.throws( 124 () => fs.fstatSync(fd), 125 validateError 126 ); 127 }); 128} 129 130// realpath 131{ 132 const validateError = (err) => { 133 assert.strictEqual(nonexistentFile, err.path); 134 assert.strictEqual( 135 err.message, 136 `ENOENT: no such file or directory, lstat '${nonexistentFile}'`); 137 assert.strictEqual(err.errno, UV_ENOENT); 138 assert.strictEqual(err.code, 'ENOENT'); 139 assert.strictEqual(err.syscall, 'lstat'); 140 return true; 141 }; 142 143 fs.realpath(nonexistentFile, common.mustCall(validateError)); 144 145 assert.throws( 146 () => fs.realpathSync(nonexistentFile), 147 validateError 148 ); 149} 150 151// native realpath 152{ 153 const validateError = (err) => { 154 assert.strictEqual(nonexistentFile, err.path); 155 assert.strictEqual( 156 err.message, 157 `ENOENT: no such file or directory, realpath '${nonexistentFile}'`); 158 assert.strictEqual(err.errno, UV_ENOENT); 159 assert.strictEqual(err.code, 'ENOENT'); 160 assert.strictEqual(err.syscall, 'realpath'); 161 return true; 162 }; 163 164 fs.realpath.native(nonexistentFile, common.mustCall(validateError)); 165 166 assert.throws( 167 () => fs.realpathSync.native(nonexistentFile), 168 validateError 169 ); 170} 171 172// readlink 173{ 174 const validateError = (err) => { 175 assert.strictEqual(nonexistentFile, err.path); 176 assert.strictEqual( 177 err.message, 178 `ENOENT: no such file or directory, readlink '${nonexistentFile}'`); 179 assert.strictEqual(err.errno, UV_ENOENT); 180 assert.strictEqual(err.code, 'ENOENT'); 181 assert.strictEqual(err.syscall, 'readlink'); 182 return true; 183 }; 184 185 fs.readlink(nonexistentFile, common.mustCall(validateError)); 186 187 assert.throws( 188 () => fs.readlinkSync(nonexistentFile), 189 validateError 190 ); 191} 192 193// Link nonexistent file 194{ 195 const validateError = (err) => { 196 assert.strictEqual(nonexistentFile, err.path); 197 // Could be resolved to an absolute path 198 assert.ok(err.dest.endsWith('foo'), 199 `expect ${err.dest} to end with 'foo'`); 200 const regexp = new RegExp('^ENOENT: no such file or directory, link ' + 201 re`'${nonexistentFile}' -> ` + '\'.*foo\''); 202 assert.ok(regexp.test(err.message), 203 `Expect ${err.message} to match ${regexp}`); 204 assert.strictEqual(err.errno, UV_ENOENT); 205 assert.strictEqual(err.code, 'ENOENT'); 206 assert.strictEqual(err.syscall, 'link'); 207 return true; 208 }; 209 210 fs.link(nonexistentFile, 'foo', common.mustCall(validateError)); 211 212 assert.throws( 213 () => fs.linkSync(nonexistentFile, 'foo'), 214 validateError 215 ); 216} 217 218// link existing file 219{ 220 const validateError = (err) => { 221 assert.strictEqual(existingFile, err.path); 222 assert.strictEqual(existingFile2, err.dest); 223 assert.strictEqual( 224 err.message, 225 `EEXIST: file already exists, link '${existingFile}' -> ` + 226 `'${existingFile2}'`); 227 assert.strictEqual(err.errno, UV_EEXIST); 228 assert.strictEqual(err.code, 'EEXIST'); 229 assert.strictEqual(err.syscall, 'link'); 230 return true; 231 }; 232 233 fs.link(existingFile, existingFile2, common.mustCall(validateError)); 234 235 assert.throws( 236 () => fs.linkSync(existingFile, existingFile2), 237 validateError 238 ); 239} 240 241// symlink 242{ 243 const validateError = (err) => { 244 assert.strictEqual(existingFile, err.path); 245 assert.strictEqual(existingFile2, err.dest); 246 assert.strictEqual( 247 err.message, 248 `EEXIST: file already exists, symlink '${existingFile}' -> ` + 249 `'${existingFile2}'`); 250 assert.strictEqual(err.errno, UV_EEXIST); 251 assert.strictEqual(err.code, 'EEXIST'); 252 assert.strictEqual(err.syscall, 'symlink'); 253 return true; 254 }; 255 256 fs.symlink(existingFile, existingFile2, common.mustCall(validateError)); 257 258 assert.throws( 259 () => fs.symlinkSync(existingFile, existingFile2), 260 validateError 261 ); 262} 263 264// unlink 265{ 266 const validateError = (err) => { 267 assert.strictEqual(nonexistentFile, err.path); 268 assert.strictEqual( 269 err.message, 270 `ENOENT: no such file or directory, unlink '${nonexistentFile}'`); 271 assert.strictEqual(err.errno, UV_ENOENT); 272 assert.strictEqual(err.code, 'ENOENT'); 273 assert.strictEqual(err.syscall, 'unlink'); 274 return true; 275 }; 276 277 fs.unlink(nonexistentFile, common.mustCall(validateError)); 278 279 assert.throws( 280 () => fs.unlinkSync(nonexistentFile), 281 validateError 282 ); 283} 284 285// rename 286{ 287 const validateError = (err) => { 288 assert.strictEqual(nonexistentFile, err.path); 289 // Could be resolved to an absolute path 290 assert.ok(err.dest.endsWith('foo'), 291 `expect ${err.dest} to end with 'foo'`); 292 const regexp = new RegExp('ENOENT: no such file or directory, rename ' + 293 re`'${nonexistentFile}' -> ` + '\'.*foo\''); 294 assert.ok(regexp.test(err.message), 295 `Expect ${err.message} to match ${regexp}`); 296 assert.strictEqual(err.errno, UV_ENOENT); 297 assert.strictEqual(err.code, 'ENOENT'); 298 assert.strictEqual(err.syscall, 'rename'); 299 return true; 300 }; 301 302 const destFile = path.join(tmpdir.path, 'foo'); 303 fs.rename(nonexistentFile, destFile, common.mustCall(validateError)); 304 305 assert.throws( 306 () => fs.renameSync(nonexistentFile, destFile), 307 validateError 308 ); 309} 310 311// Rename non-empty directory 312{ 313 const validateError = (err) => { 314 assert.strictEqual(existingDir, err.path); 315 assert.strictEqual(existingDir2, err.dest); 316 assert.strictEqual(err.syscall, 'rename'); 317 // Could be ENOTEMPTY, EEXIST, or EPERM, depending on the platform 318 if (err.code === 'ENOTEMPTY') { 319 assert.strictEqual( 320 err.message, 321 `ENOTEMPTY: directory not empty, rename '${existingDir}' -> ` + 322 `'${existingDir2}'`); 323 assert.strictEqual(err.errno, UV_ENOTEMPTY); 324 } else if (err.code === 'EXDEV') { // Not on the same mounted filesystem 325 assert.strictEqual( 326 err.message, 327 `EXDEV: cross-device link not permitted, rename '${existingDir}' -> ` + 328 `'${existingDir2}'`); 329 } else if (err.code === 'EEXIST') { // smartos and aix 330 assert.strictEqual( 331 err.message, 332 `EEXIST: file already exists, rename '${existingDir}' -> ` + 333 `'${existingDir2}'`); 334 assert.strictEqual(err.errno, UV_EEXIST); 335 } else { // windows 336 assert.strictEqual( 337 err.message, 338 `EPERM: operation not permitted, rename '${existingDir}' -> ` + 339 `'${existingDir2}'`); 340 assert.strictEqual(err.errno, UV_EPERM); 341 assert.strictEqual(err.code, 'EPERM'); 342 } 343 return true; 344 }; 345 346 fs.rename(existingDir, existingDir2, common.mustCall(validateError)); 347 348 assert.throws( 349 () => fs.renameSync(existingDir, existingDir2), 350 validateError 351 ); 352} 353 354// rmdir 355{ 356 const validateError = (err) => { 357 assert.strictEqual(nonexistentFile, err.path); 358 assert.strictEqual( 359 err.message, 360 `ENOENT: no such file or directory, rmdir '${nonexistentFile}'`); 361 assert.strictEqual(err.errno, UV_ENOENT); 362 assert.strictEqual(err.code, 'ENOENT'); 363 assert.strictEqual(err.syscall, 'rmdir'); 364 return true; 365 }; 366 367 fs.rmdir(nonexistentFile, common.mustCall(validateError)); 368 369 assert.throws( 370 () => fs.rmdirSync(nonexistentFile), 371 validateError 372 ); 373} 374 375// rmdir a file 376{ 377 const validateError = (err) => { 378 assert.strictEqual(existingFile, err.path); 379 assert.strictEqual(err.syscall, 'rmdir'); 380 if (err.code === 'ENOTDIR') { 381 assert.strictEqual( 382 err.message, 383 `ENOTDIR: not a directory, rmdir '${existingFile}'`); 384 assert.strictEqual(err.errno, UV_ENOTDIR); 385 } else { // windows 386 assert.strictEqual( 387 err.message, 388 `ENOENT: no such file or directory, rmdir '${existingFile}'`); 389 assert.strictEqual(err.errno, UV_ENOENT); 390 assert.strictEqual(err.code, 'ENOENT'); 391 } 392 return true; 393 }; 394 395 fs.rmdir(existingFile, common.mustCall(validateError)); 396 397 assert.throws( 398 () => fs.rmdirSync(existingFile), 399 validateError 400 ); 401} 402 403// mkdir 404{ 405 const validateError = (err) => { 406 assert.strictEqual(existingFile, err.path); 407 assert.strictEqual( 408 err.message, 409 `EEXIST: file already exists, mkdir '${existingFile}'`); 410 assert.strictEqual(err.errno, UV_EEXIST); 411 assert.strictEqual(err.code, 'EEXIST'); 412 assert.strictEqual(err.syscall, 'mkdir'); 413 return true; 414 }; 415 416 fs.mkdir(existingFile, 0o666, common.mustCall(validateError)); 417 418 assert.throws( 419 () => fs.mkdirSync(existingFile, 0o666), 420 validateError 421 ); 422} 423 424// chmod 425{ 426 const validateError = (err) => { 427 assert.strictEqual(nonexistentFile, err.path); 428 assert.strictEqual( 429 err.message, 430 `ENOENT: no such file or directory, chmod '${nonexistentFile}'`); 431 assert.strictEqual(err.errno, UV_ENOENT); 432 assert.strictEqual(err.code, 'ENOENT'); 433 assert.strictEqual(err.syscall, 'chmod'); 434 return true; 435 }; 436 437 fs.chmod(nonexistentFile, 0o666, common.mustCall(validateError)); 438 439 assert.throws( 440 () => fs.chmodSync(nonexistentFile, 0o666), 441 validateError 442 ); 443} 444 445// open 446{ 447 const validateError = (err) => { 448 assert.strictEqual(nonexistentFile, err.path); 449 assert.strictEqual( 450 err.message, 451 `ENOENT: no such file or directory, open '${nonexistentFile}'`); 452 assert.strictEqual(err.errno, UV_ENOENT); 453 assert.strictEqual(err.code, 'ENOENT'); 454 assert.strictEqual(err.syscall, 'open'); 455 return true; 456 }; 457 458 fs.open(nonexistentFile, 'r', 0o666, common.mustCall(validateError)); 459 460 assert.throws( 461 () => fs.openSync(nonexistentFile, 'r', 0o666), 462 validateError 463 ); 464} 465 466 467// close 468{ 469 const validateError = (err) => { 470 assert.strictEqual(err.message, 'EBADF: bad file descriptor, close'); 471 assert.strictEqual(err.errno, UV_EBADF); 472 assert.strictEqual(err.code, 'EBADF'); 473 assert.strictEqual(err.syscall, 'close'); 474 return true; 475 }; 476 477 common.runWithInvalidFD((fd) => { 478 fs.close(fd, common.mustCall(validateError)); 479 480 assert.throws( 481 () => fs.closeSync(fd), 482 validateError 483 ); 484 }); 485} 486 487// readFile 488{ 489 const validateError = (err) => { 490 assert.strictEqual(nonexistentFile, err.path); 491 assert.strictEqual( 492 err.message, 493 `ENOENT: no such file or directory, open '${nonexistentFile}'`); 494 assert.strictEqual(err.errno, UV_ENOENT); 495 assert.strictEqual(err.code, 'ENOENT'); 496 assert.strictEqual(err.syscall, 'open'); 497 return true; 498 }; 499 500 fs.readFile(nonexistentFile, common.mustCall(validateError)); 501 502 assert.throws( 503 () => fs.readFileSync(nonexistentFile), 504 validateError 505 ); 506} 507 508// readdir 509{ 510 const validateError = (err) => { 511 assert.strictEqual(nonexistentFile, err.path); 512 assert.strictEqual( 513 err.message, 514 `ENOENT: no such file or directory, scandir '${nonexistentFile}'`); 515 assert.strictEqual(err.errno, UV_ENOENT); 516 assert.strictEqual(err.code, 'ENOENT'); 517 assert.strictEqual(err.syscall, 'scandir'); 518 return true; 519 }; 520 521 fs.readdir(nonexistentFile, common.mustCall(validateError)); 522 523 assert.throws( 524 () => fs.readdirSync(nonexistentFile), 525 validateError 526 ); 527} 528 529// ftruncate 530{ 531 const validateError = (err) => { 532 assert.strictEqual(err.syscall, 'ftruncate'); 533 // Could be EBADF or EINVAL, depending on the platform 534 if (err.code === 'EBADF') { 535 assert.strictEqual(err.message, 'EBADF: bad file descriptor, ftruncate'); 536 assert.strictEqual(err.errno, UV_EBADF); 537 } else { 538 assert.strictEqual(err.message, 'EINVAL: invalid argument, ftruncate'); 539 assert.strictEqual(err.errno, UV_EINVAL); 540 assert.strictEqual(err.code, 'EINVAL'); 541 } 542 return true; 543 }; 544 545 common.runWithInvalidFD((fd) => { 546 fs.ftruncate(fd, 4, common.mustCall(validateError)); 547 548 assert.throws( 549 () => fs.ftruncateSync(fd, 4), 550 validateError 551 ); 552 }); 553} 554 555// fdatasync 556{ 557 const validateError = (err) => { 558 assert.strictEqual(err.message, 'EBADF: bad file descriptor, fdatasync'); 559 assert.strictEqual(err.errno, UV_EBADF); 560 assert.strictEqual(err.code, 'EBADF'); 561 assert.strictEqual(err.syscall, 'fdatasync'); 562 return true; 563 }; 564 565 common.runWithInvalidFD((fd) => { 566 fs.fdatasync(fd, common.mustCall(validateError)); 567 568 assert.throws( 569 () => fs.fdatasyncSync(fd), 570 validateError 571 ); 572 }); 573} 574 575// fsync 576{ 577 const validateError = (err) => { 578 assert.strictEqual(err.message, 'EBADF: bad file descriptor, fsync'); 579 assert.strictEqual(err.errno, UV_EBADF); 580 assert.strictEqual(err.code, 'EBADF'); 581 assert.strictEqual(err.syscall, 'fsync'); 582 return true; 583 }; 584 585 common.runWithInvalidFD((fd) => { 586 fs.fsync(fd, common.mustCall(validateError)); 587 588 assert.throws( 589 () => fs.fsyncSync(fd), 590 validateError 591 ); 592 }); 593} 594 595// chown 596if (!common.isWindows) { 597 const validateError = (err) => { 598 assert.strictEqual(nonexistentFile, err.path); 599 assert.strictEqual( 600 err.message, 601 `ENOENT: no such file or directory, chown '${nonexistentFile}'`); 602 assert.strictEqual(err.errno, UV_ENOENT); 603 assert.strictEqual(err.code, 'ENOENT'); 604 assert.strictEqual(err.syscall, 'chown'); 605 return true; 606 }; 607 608 fs.chown(nonexistentFile, process.getuid(), process.getgid(), 609 common.mustCall(validateError)); 610 611 assert.throws( 612 () => fs.chownSync(nonexistentFile, 613 process.getuid(), process.getgid()), 614 validateError 615 ); 616} 617 618// utimes 619if (!common.isAIX) { 620 const validateError = (err) => { 621 assert.strictEqual(nonexistentFile, err.path); 622 assert.strictEqual( 623 err.message, 624 `ENOENT: no such file or directory, utime '${nonexistentFile}'`); 625 assert.strictEqual(err.errno, UV_ENOENT); 626 assert.strictEqual(err.code, 'ENOENT'); 627 assert.strictEqual(err.syscall, 'utime'); 628 return true; 629 }; 630 631 fs.utimes(nonexistentFile, new Date(), new Date(), 632 common.mustCall(validateError)); 633 634 assert.throws( 635 () => fs.utimesSync(nonexistentFile, new Date(), new Date()), 636 validateError 637 ); 638} 639 640// mkdtemp 641{ 642 const validateError = (err) => { 643 const pathPrefix = new RegExp('^' + re`${nonexistentDir}`); 644 assert(pathPrefix.test(err.path), 645 `Expect ${err.path} to match ${pathPrefix}`); 646 647 const prefix = new RegExp('^ENOENT: no such file or directory, mkdtemp ' + 648 re`'${nonexistentDir}`); 649 assert(prefix.test(err.message), 650 `Expect ${err.message} to match ${prefix}`); 651 652 assert.strictEqual(err.errno, UV_ENOENT); 653 assert.strictEqual(err.code, 'ENOENT'); 654 assert.strictEqual(err.syscall, 'mkdtemp'); 655 return true; 656 }; 657 658 fs.mkdtemp(nonexistentDir, common.mustCall(validateError)); 659 660 assert.throws( 661 () => fs.mkdtempSync(nonexistentDir), 662 validateError 663 ); 664} 665 666// Check copyFile with invalid modes. 667{ 668 const validateError = { 669 message: /"mode".+must be an integer >= 0 && <= 7\. Received -1/, 670 code: 'ERR_OUT_OF_RANGE' 671 }; 672 673 assert.throws( 674 () => fs.copyFile(existingFile, nonexistentFile, -1, () => {}), 675 validateError 676 ); 677 assert.throws( 678 () => fs.copyFileSync(existingFile, nonexistentFile, -1), 679 validateError 680 ); 681} 682 683// copyFile: destination exists but the COPYFILE_EXCL flag is provided. 684{ 685 const validateError = (err) => { 686 if (err.code === 'ENOENT') { // Could be ENOENT or EEXIST 687 assert.strictEqual(err.message, 688 'ENOENT: no such file or directory, copyfile ' + 689 `'${existingFile}' -> '${existingFile2}'`); 690 assert.strictEqual(err.errno, UV_ENOENT); 691 assert.strictEqual(err.code, 'ENOENT'); 692 assert.strictEqual(err.syscall, 'copyfile'); 693 } else { 694 assert.strictEqual(err.message, 695 'EEXIST: file already exists, copyfile ' + 696 `'${existingFile}' -> '${existingFile2}'`); 697 assert.strictEqual(err.errno, UV_EEXIST); 698 assert.strictEqual(err.code, 'EEXIST'); 699 assert.strictEqual(err.syscall, 'copyfile'); 700 } 701 return true; 702 }; 703 704 fs.copyFile(existingFile, existingFile2, COPYFILE_EXCL, 705 common.mustCall(validateError)); 706 707 assert.throws( 708 () => fs.copyFileSync(existingFile, existingFile2, COPYFILE_EXCL), 709 validateError 710 ); 711} 712 713// copyFile: the source does not exist. 714{ 715 const validateError = (err) => { 716 assert.strictEqual(err.message, 717 'ENOENT: no such file or directory, copyfile ' + 718 `'${nonexistentFile}' -> '${existingFile2}'`); 719 assert.strictEqual(err.errno, UV_ENOENT); 720 assert.strictEqual(err.code, 'ENOENT'); 721 assert.strictEqual(err.syscall, 'copyfile'); 722 return true; 723 }; 724 725 fs.copyFile(nonexistentFile, existingFile2, COPYFILE_EXCL, 726 common.mustCall(validateError)); 727 728 assert.throws( 729 () => fs.copyFileSync(nonexistentFile, existingFile2, COPYFILE_EXCL), 730 validateError 731 ); 732} 733 734// read 735{ 736 const validateError = (err) => { 737 assert.strictEqual(err.message, 'EBADF: bad file descriptor, read'); 738 assert.strictEqual(err.errno, UV_EBADF); 739 assert.strictEqual(err.code, 'EBADF'); 740 assert.strictEqual(err.syscall, 'read'); 741 return true; 742 }; 743 744 common.runWithInvalidFD((fd) => { 745 const buf = Buffer.alloc(5); 746 fs.read(fd, buf, 0, 1, 1, common.mustCall(validateError)); 747 748 assert.throws( 749 () => fs.readSync(fd, buf, 0, 1, 1), 750 validateError 751 ); 752 }); 753} 754 755// fchmod 756{ 757 const validateError = (err) => { 758 assert.strictEqual(err.message, 'EBADF: bad file descriptor, fchmod'); 759 assert.strictEqual(err.errno, UV_EBADF); 760 assert.strictEqual(err.code, 'EBADF'); 761 assert.strictEqual(err.syscall, 'fchmod'); 762 return true; 763 }; 764 765 common.runWithInvalidFD((fd) => { 766 fs.fchmod(fd, 0o666, common.mustCall(validateError)); 767 768 assert.throws( 769 () => fs.fchmodSync(fd, 0o666), 770 validateError 771 ); 772 }); 773} 774 775// fchown 776if (!common.isWindows) { 777 const validateError = (err) => { 778 assert.strictEqual(err.message, 'EBADF: bad file descriptor, fchown'); 779 assert.strictEqual(err.errno, UV_EBADF); 780 assert.strictEqual(err.code, 'EBADF'); 781 assert.strictEqual(err.syscall, 'fchown'); 782 return true; 783 }; 784 785 common.runWithInvalidFD((fd) => { 786 fs.fchown(fd, process.getuid(), process.getgid(), 787 common.mustCall(validateError)); 788 789 assert.throws( 790 () => fs.fchownSync(fd, process.getuid(), process.getgid()), 791 validateError 792 ); 793 }); 794} 795 796// write buffer 797{ 798 const validateError = (err) => { 799 assert.strictEqual(err.message, 'EBADF: bad file descriptor, write'); 800 assert.strictEqual(err.errno, UV_EBADF); 801 assert.strictEqual(err.code, 'EBADF'); 802 assert.strictEqual(err.syscall, 'write'); 803 return true; 804 }; 805 806 common.runWithInvalidFD((fd) => { 807 const buf = Buffer.alloc(5); 808 fs.write(fd, buf, 0, 1, 1, common.mustCall(validateError)); 809 810 assert.throws( 811 () => fs.writeSync(fd, buf, 0, 1, 1), 812 validateError 813 ); 814 }); 815} 816 817// write string 818{ 819 const validateError = (err) => { 820 assert.strictEqual(err.message, 'EBADF: bad file descriptor, write'); 821 assert.strictEqual(err.errno, UV_EBADF); 822 assert.strictEqual(err.code, 'EBADF'); 823 assert.strictEqual(err.syscall, 'write'); 824 return true; 825 }; 826 827 common.runWithInvalidFD((fd) => { 828 fs.write(fd, 'test', 1, common.mustCall(validateError)); 829 830 assert.throws( 831 () => fs.writeSync(fd, 'test', 1), 832 validateError 833 ); 834 }); 835} 836 837 838// futimes 839if (!common.isAIX) { 840 const validateError = (err) => { 841 assert.strictEqual(err.message, 'EBADF: bad file descriptor, futime'); 842 assert.strictEqual(err.errno, UV_EBADF); 843 assert.strictEqual(err.code, 'EBADF'); 844 assert.strictEqual(err.syscall, 'futime'); 845 return true; 846 }; 847 848 common.runWithInvalidFD((fd) => { 849 fs.futimes(fd, new Date(), new Date(), common.mustCall(validateError)); 850 851 assert.throws( 852 () => fs.futimesSync(fd, new Date(), new Date()), 853 validateError 854 ); 855 }); 856} 857