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.match(err.message, regexp); 203 assert.strictEqual(err.errno, UV_ENOENT); 204 assert.strictEqual(err.code, 'ENOENT'); 205 assert.strictEqual(err.syscall, 'link'); 206 return true; 207 }; 208 209 fs.link(nonexistentFile, 'foo', common.mustCall(validateError)); 210 211 assert.throws( 212 () => fs.linkSync(nonexistentFile, 'foo'), 213 validateError 214 ); 215} 216 217// link existing file 218{ 219 const validateError = (err) => { 220 assert.strictEqual(existingFile, err.path); 221 assert.strictEqual(existingFile2, err.dest); 222 assert.strictEqual( 223 err.message, 224 `EEXIST: file already exists, link '${existingFile}' -> ` + 225 `'${existingFile2}'`); 226 assert.strictEqual(err.errno, UV_EEXIST); 227 assert.strictEqual(err.code, 'EEXIST'); 228 assert.strictEqual(err.syscall, 'link'); 229 return true; 230 }; 231 232 fs.link(existingFile, existingFile2, common.mustCall(validateError)); 233 234 assert.throws( 235 () => fs.linkSync(existingFile, existingFile2), 236 validateError 237 ); 238} 239 240// symlink 241{ 242 const validateError = (err) => { 243 assert.strictEqual(existingFile, err.path); 244 assert.strictEqual(existingFile2, err.dest); 245 assert.strictEqual( 246 err.message, 247 `EEXIST: file already exists, symlink '${existingFile}' -> ` + 248 `'${existingFile2}'`); 249 assert.strictEqual(err.errno, UV_EEXIST); 250 assert.strictEqual(err.code, 'EEXIST'); 251 assert.strictEqual(err.syscall, 'symlink'); 252 return true; 253 }; 254 255 fs.symlink(existingFile, existingFile2, common.mustCall(validateError)); 256 257 assert.throws( 258 () => fs.symlinkSync(existingFile, existingFile2), 259 validateError 260 ); 261} 262 263// unlink 264{ 265 const validateError = (err) => { 266 assert.strictEqual(nonexistentFile, err.path); 267 assert.strictEqual( 268 err.message, 269 `ENOENT: no such file or directory, unlink '${nonexistentFile}'`); 270 assert.strictEqual(err.errno, UV_ENOENT); 271 assert.strictEqual(err.code, 'ENOENT'); 272 assert.strictEqual(err.syscall, 'unlink'); 273 return true; 274 }; 275 276 fs.unlink(nonexistentFile, common.mustCall(validateError)); 277 278 assert.throws( 279 () => fs.unlinkSync(nonexistentFile), 280 validateError 281 ); 282} 283 284// rename 285{ 286 const validateError = (err) => { 287 assert.strictEqual(nonexistentFile, err.path); 288 // Could be resolved to an absolute path 289 assert.ok(err.dest.endsWith('foo'), 290 `expect ${err.dest} to end with 'foo'`); 291 const regexp = new RegExp('ENOENT: no such file or directory, rename ' + 292 re`'${nonexistentFile}' -> ` + '\'.*foo\''); 293 assert.match(err.message, regexp); 294 assert.strictEqual(err.errno, UV_ENOENT); 295 assert.strictEqual(err.code, 'ENOENT'); 296 assert.strictEqual(err.syscall, 'rename'); 297 return true; 298 }; 299 300 const destFile = path.join(tmpdir.path, 'foo'); 301 fs.rename(nonexistentFile, destFile, common.mustCall(validateError)); 302 303 assert.throws( 304 () => fs.renameSync(nonexistentFile, destFile), 305 validateError 306 ); 307} 308 309// Rename non-empty directory 310{ 311 const validateError = (err) => { 312 assert.strictEqual(existingDir, err.path); 313 assert.strictEqual(existingDir2, err.dest); 314 assert.strictEqual(err.syscall, 'rename'); 315 // Could be ENOTEMPTY, EEXIST, or EPERM, depending on the platform 316 if (err.code === 'ENOTEMPTY') { 317 assert.strictEqual( 318 err.message, 319 `ENOTEMPTY: directory not empty, rename '${existingDir}' -> ` + 320 `'${existingDir2}'`); 321 assert.strictEqual(err.errno, UV_ENOTEMPTY); 322 } else if (err.code === 'EXDEV') { // Not on the same mounted filesystem 323 assert.strictEqual( 324 err.message, 325 `EXDEV: cross-device link not permitted, rename '${existingDir}' -> ` + 326 `'${existingDir2}'`); 327 } else if (err.code === 'EEXIST') { // smartos and aix 328 assert.strictEqual( 329 err.message, 330 `EEXIST: file already exists, rename '${existingDir}' -> ` + 331 `'${existingDir2}'`); 332 assert.strictEqual(err.errno, UV_EEXIST); 333 } else { // windows 334 assert.strictEqual( 335 err.message, 336 `EPERM: operation not permitted, rename '${existingDir}' -> ` + 337 `'${existingDir2}'`); 338 assert.strictEqual(err.errno, UV_EPERM); 339 assert.strictEqual(err.code, 'EPERM'); 340 } 341 return true; 342 }; 343 344 fs.rename(existingDir, existingDir2, common.mustCall(validateError)); 345 346 assert.throws( 347 () => fs.renameSync(existingDir, existingDir2), 348 validateError 349 ); 350} 351 352// rmdir 353{ 354 const validateError = (err) => { 355 assert.strictEqual(nonexistentFile, err.path); 356 assert.strictEqual( 357 err.message, 358 `ENOENT: no such file or directory, rmdir '${nonexistentFile}'`); 359 assert.strictEqual(err.errno, UV_ENOENT); 360 assert.strictEqual(err.code, 'ENOENT'); 361 assert.strictEqual(err.syscall, 'rmdir'); 362 return true; 363 }; 364 365 fs.rmdir(nonexistentFile, common.mustCall(validateError)); 366 367 assert.throws( 368 () => fs.rmdirSync(nonexistentFile), 369 validateError 370 ); 371} 372 373// rmdir a file 374{ 375 const validateError = (err) => { 376 assert.strictEqual(existingFile, err.path); 377 assert.strictEqual(err.syscall, 'rmdir'); 378 if (err.code === 'ENOTDIR') { 379 assert.strictEqual( 380 err.message, 381 `ENOTDIR: not a directory, rmdir '${existingFile}'`); 382 assert.strictEqual(err.errno, UV_ENOTDIR); 383 } else { // windows 384 assert.strictEqual( 385 err.message, 386 `ENOENT: no such file or directory, rmdir '${existingFile}'`); 387 assert.strictEqual(err.errno, UV_ENOENT); 388 assert.strictEqual(err.code, 'ENOENT'); 389 } 390 return true; 391 }; 392 393 fs.rmdir(existingFile, common.mustCall(validateError)); 394 395 assert.throws( 396 () => fs.rmdirSync(existingFile), 397 validateError 398 ); 399} 400 401// mkdir 402{ 403 const validateError = (err) => { 404 assert.strictEqual(existingFile, err.path); 405 assert.strictEqual( 406 err.message, 407 `EEXIST: file already exists, mkdir '${existingFile}'`); 408 assert.strictEqual(err.errno, UV_EEXIST); 409 assert.strictEqual(err.code, 'EEXIST'); 410 assert.strictEqual(err.syscall, 'mkdir'); 411 return true; 412 }; 413 414 fs.mkdir(existingFile, 0o666, common.mustCall(validateError)); 415 416 assert.throws( 417 () => fs.mkdirSync(existingFile, 0o666), 418 validateError 419 ); 420} 421 422// chmod 423{ 424 const validateError = (err) => { 425 assert.strictEqual(nonexistentFile, err.path); 426 assert.strictEqual( 427 err.message, 428 `ENOENT: no such file or directory, chmod '${nonexistentFile}'`); 429 assert.strictEqual(err.errno, UV_ENOENT); 430 assert.strictEqual(err.code, 'ENOENT'); 431 assert.strictEqual(err.syscall, 'chmod'); 432 return true; 433 }; 434 435 fs.chmod(nonexistentFile, 0o666, common.mustCall(validateError)); 436 437 assert.throws( 438 () => fs.chmodSync(nonexistentFile, 0o666), 439 validateError 440 ); 441} 442 443// open 444{ 445 const validateError = (err) => { 446 assert.strictEqual(nonexistentFile, err.path); 447 assert.strictEqual( 448 err.message, 449 `ENOENT: no such file or directory, open '${nonexistentFile}'`); 450 assert.strictEqual(err.errno, UV_ENOENT); 451 assert.strictEqual(err.code, 'ENOENT'); 452 assert.strictEqual(err.syscall, 'open'); 453 return true; 454 }; 455 456 fs.open(nonexistentFile, 'r', 0o666, common.mustCall(validateError)); 457 458 assert.throws( 459 () => fs.openSync(nonexistentFile, 'r', 0o666), 460 validateError 461 ); 462} 463 464 465// close 466{ 467 const validateError = (err) => { 468 assert.strictEqual(err.message, 'EBADF: bad file descriptor, close'); 469 assert.strictEqual(err.errno, UV_EBADF); 470 assert.strictEqual(err.code, 'EBADF'); 471 assert.strictEqual(err.syscall, 'close'); 472 return true; 473 }; 474 475 common.runWithInvalidFD((fd) => { 476 fs.close(fd, common.mustCall(validateError)); 477 478 assert.throws( 479 () => fs.closeSync(fd), 480 validateError 481 ); 482 }); 483} 484 485// readFile 486{ 487 const validateError = (err) => { 488 assert.strictEqual(nonexistentFile, err.path); 489 assert.strictEqual( 490 err.message, 491 `ENOENT: no such file or directory, open '${nonexistentFile}'`); 492 assert.strictEqual(err.errno, UV_ENOENT); 493 assert.strictEqual(err.code, 'ENOENT'); 494 assert.strictEqual(err.syscall, 'open'); 495 return true; 496 }; 497 498 fs.readFile(nonexistentFile, common.mustCall(validateError)); 499 500 assert.throws( 501 () => fs.readFileSync(nonexistentFile), 502 validateError 503 ); 504} 505 506// readdir 507{ 508 const validateError = (err) => { 509 assert.strictEqual(nonexistentFile, err.path); 510 assert.strictEqual( 511 err.message, 512 `ENOENT: no such file or directory, scandir '${nonexistentFile}'`); 513 assert.strictEqual(err.errno, UV_ENOENT); 514 assert.strictEqual(err.code, 'ENOENT'); 515 assert.strictEqual(err.syscall, 'scandir'); 516 return true; 517 }; 518 519 fs.readdir(nonexistentFile, common.mustCall(validateError)); 520 521 assert.throws( 522 () => fs.readdirSync(nonexistentFile), 523 validateError 524 ); 525} 526 527// ftruncate 528{ 529 const validateError = (err) => { 530 assert.strictEqual(err.syscall, 'ftruncate'); 531 // Could be EBADF or EINVAL, depending on the platform 532 if (err.code === 'EBADF') { 533 assert.strictEqual(err.message, 'EBADF: bad file descriptor, ftruncate'); 534 assert.strictEqual(err.errno, UV_EBADF); 535 } else { 536 assert.strictEqual(err.message, 'EINVAL: invalid argument, ftruncate'); 537 assert.strictEqual(err.errno, UV_EINVAL); 538 assert.strictEqual(err.code, 'EINVAL'); 539 } 540 return true; 541 }; 542 543 common.runWithInvalidFD((fd) => { 544 fs.ftruncate(fd, 4, common.mustCall(validateError)); 545 546 assert.throws( 547 () => fs.ftruncateSync(fd, 4), 548 validateError 549 ); 550 }); 551} 552 553// fdatasync 554{ 555 const validateError = (err) => { 556 assert.strictEqual(err.message, 'EBADF: bad file descriptor, fdatasync'); 557 assert.strictEqual(err.errno, UV_EBADF); 558 assert.strictEqual(err.code, 'EBADF'); 559 assert.strictEqual(err.syscall, 'fdatasync'); 560 return true; 561 }; 562 563 common.runWithInvalidFD((fd) => { 564 fs.fdatasync(fd, common.mustCall(validateError)); 565 566 assert.throws( 567 () => fs.fdatasyncSync(fd), 568 validateError 569 ); 570 }); 571} 572 573// fsync 574{ 575 const validateError = (err) => { 576 assert.strictEqual(err.message, 'EBADF: bad file descriptor, fsync'); 577 assert.strictEqual(err.errno, UV_EBADF); 578 assert.strictEqual(err.code, 'EBADF'); 579 assert.strictEqual(err.syscall, 'fsync'); 580 return true; 581 }; 582 583 common.runWithInvalidFD((fd) => { 584 fs.fsync(fd, common.mustCall(validateError)); 585 586 assert.throws( 587 () => fs.fsyncSync(fd), 588 validateError 589 ); 590 }); 591} 592 593// chown 594if (!common.isWindows) { 595 const validateError = (err) => { 596 assert.strictEqual(nonexistentFile, err.path); 597 assert.strictEqual( 598 err.message, 599 `ENOENT: no such file or directory, chown '${nonexistentFile}'`); 600 assert.strictEqual(err.errno, UV_ENOENT); 601 assert.strictEqual(err.code, 'ENOENT'); 602 assert.strictEqual(err.syscall, 'chown'); 603 return true; 604 }; 605 606 fs.chown(nonexistentFile, process.getuid(), process.getgid(), 607 common.mustCall(validateError)); 608 609 assert.throws( 610 () => fs.chownSync(nonexistentFile, 611 process.getuid(), process.getgid()), 612 validateError 613 ); 614} 615 616// utimes 617if (!common.isAIX) { 618 const validateError = (err) => { 619 assert.strictEqual(nonexistentFile, err.path); 620 assert.strictEqual( 621 err.message, 622 `ENOENT: no such file or directory, utime '${nonexistentFile}'`); 623 assert.strictEqual(err.errno, UV_ENOENT); 624 assert.strictEqual(err.code, 'ENOENT'); 625 assert.strictEqual(err.syscall, 'utime'); 626 return true; 627 }; 628 629 fs.utimes(nonexistentFile, new Date(), new Date(), 630 common.mustCall(validateError)); 631 632 assert.throws( 633 () => fs.utimesSync(nonexistentFile, new Date(), new Date()), 634 validateError 635 ); 636} 637 638// mkdtemp 639{ 640 const validateError = (err) => { 641 const pathPrefix = new RegExp('^' + re`${nonexistentDir}`); 642 assert.match(err.path, pathPrefix); 643 644 const prefix = new RegExp('^ENOENT: no such file or directory, mkdtemp ' + 645 re`'${nonexistentDir}`); 646 assert.match(err.message, prefix); 647 648 assert.strictEqual(err.errno, UV_ENOENT); 649 assert.strictEqual(err.code, 'ENOENT'); 650 assert.strictEqual(err.syscall, 'mkdtemp'); 651 return true; 652 }; 653 654 fs.mkdtemp(nonexistentDir, common.mustCall(validateError)); 655 656 assert.throws( 657 () => fs.mkdtempSync(nonexistentDir), 658 validateError 659 ); 660} 661 662// Check copyFile with invalid modes. 663{ 664 const validateError = { 665 code: 'ERR_OUT_OF_RANGE', 666 }; 667 668 assert.throws( 669 () => fs.copyFile(existingFile, nonexistentFile, -1, () => {}), 670 validateError 671 ); 672 assert.throws( 673 () => fs.copyFileSync(existingFile, nonexistentFile, -1), 674 validateError 675 ); 676} 677 678// copyFile: destination exists but the COPYFILE_EXCL flag is provided. 679{ 680 const validateError = (err) => { 681 if (err.code === 'ENOENT') { // Could be ENOENT or EEXIST 682 assert.strictEqual(err.message, 683 'ENOENT: no such file or directory, copyfile ' + 684 `'${existingFile}' -> '${existingFile2}'`); 685 assert.strictEqual(err.errno, UV_ENOENT); 686 assert.strictEqual(err.code, 'ENOENT'); 687 assert.strictEqual(err.syscall, 'copyfile'); 688 } else { 689 assert.strictEqual(err.message, 690 'EEXIST: file already exists, copyfile ' + 691 `'${existingFile}' -> '${existingFile2}'`); 692 assert.strictEqual(err.errno, UV_EEXIST); 693 assert.strictEqual(err.code, 'EEXIST'); 694 assert.strictEqual(err.syscall, 'copyfile'); 695 } 696 return true; 697 }; 698 699 fs.copyFile(existingFile, existingFile2, COPYFILE_EXCL, 700 common.mustCall(validateError)); 701 702 assert.throws( 703 () => fs.copyFileSync(existingFile, existingFile2, COPYFILE_EXCL), 704 validateError 705 ); 706} 707 708// copyFile: the source does not exist. 709{ 710 const validateError = (err) => { 711 assert.strictEqual(err.message, 712 'ENOENT: no such file or directory, copyfile ' + 713 `'${nonexistentFile}' -> '${existingFile2}'`); 714 assert.strictEqual(err.errno, UV_ENOENT); 715 assert.strictEqual(err.code, 'ENOENT'); 716 assert.strictEqual(err.syscall, 'copyfile'); 717 return true; 718 }; 719 720 fs.copyFile(nonexistentFile, existingFile2, COPYFILE_EXCL, 721 common.mustCall(validateError)); 722 723 assert.throws( 724 () => fs.copyFileSync(nonexistentFile, existingFile2, COPYFILE_EXCL), 725 validateError 726 ); 727} 728 729// read 730{ 731 const validateError = (err) => { 732 assert.strictEqual(err.message, 'EBADF: bad file descriptor, read'); 733 assert.strictEqual(err.errno, UV_EBADF); 734 assert.strictEqual(err.code, 'EBADF'); 735 assert.strictEqual(err.syscall, 'read'); 736 return true; 737 }; 738 739 common.runWithInvalidFD((fd) => { 740 const buf = Buffer.alloc(5); 741 fs.read(fd, buf, 0, 1, 1, common.mustCall(validateError)); 742 743 assert.throws( 744 () => fs.readSync(fd, buf, 0, 1, 1), 745 validateError 746 ); 747 }); 748} 749 750// fchmod 751{ 752 const validateError = (err) => { 753 assert.strictEqual(err.message, 'EBADF: bad file descriptor, fchmod'); 754 assert.strictEqual(err.errno, UV_EBADF); 755 assert.strictEqual(err.code, 'EBADF'); 756 assert.strictEqual(err.syscall, 'fchmod'); 757 return true; 758 }; 759 760 common.runWithInvalidFD((fd) => { 761 fs.fchmod(fd, 0o666, common.mustCall(validateError)); 762 763 assert.throws( 764 () => fs.fchmodSync(fd, 0o666), 765 validateError 766 ); 767 }); 768} 769 770// fchown 771if (!common.isWindows) { 772 const validateError = (err) => { 773 assert.strictEqual(err.message, 'EBADF: bad file descriptor, fchown'); 774 assert.strictEqual(err.errno, UV_EBADF); 775 assert.strictEqual(err.code, 'EBADF'); 776 assert.strictEqual(err.syscall, 'fchown'); 777 return true; 778 }; 779 780 common.runWithInvalidFD((fd) => { 781 fs.fchown(fd, process.getuid(), process.getgid(), 782 common.mustCall(validateError)); 783 784 assert.throws( 785 () => fs.fchownSync(fd, process.getuid(), process.getgid()), 786 validateError 787 ); 788 }); 789} 790 791// write buffer 792{ 793 const validateError = (err) => { 794 assert.strictEqual(err.message, 'EBADF: bad file descriptor, write'); 795 assert.strictEqual(err.errno, UV_EBADF); 796 assert.strictEqual(err.code, 'EBADF'); 797 assert.strictEqual(err.syscall, 'write'); 798 return true; 799 }; 800 801 common.runWithInvalidFD((fd) => { 802 const buf = Buffer.alloc(5); 803 fs.write(fd, buf, 0, 1, 1, common.mustCall(validateError)); 804 805 assert.throws( 806 () => fs.writeSync(fd, buf, 0, 1, 1), 807 validateError 808 ); 809 }); 810} 811 812// write string 813{ 814 const validateError = (err) => { 815 assert.strictEqual(err.message, 'EBADF: bad file descriptor, write'); 816 assert.strictEqual(err.errno, UV_EBADF); 817 assert.strictEqual(err.code, 'EBADF'); 818 assert.strictEqual(err.syscall, 'write'); 819 return true; 820 }; 821 822 common.runWithInvalidFD((fd) => { 823 fs.write(fd, 'test', 1, common.mustCall(validateError)); 824 825 assert.throws( 826 () => fs.writeSync(fd, 'test', 1), 827 validateError 828 ); 829 }); 830} 831 832 833// futimes 834if (!common.isAIX) { 835 const validateError = (err) => { 836 assert.strictEqual(err.message, 'EBADF: bad file descriptor, futime'); 837 assert.strictEqual(err.errno, UV_EBADF); 838 assert.strictEqual(err.code, 'EBADF'); 839 assert.strictEqual(err.syscall, 'futime'); 840 return true; 841 }; 842 843 common.runWithInvalidFD((fd) => { 844 fs.futimes(fd, new Date(), new Date(), common.mustCall(validateError)); 845 846 assert.throws( 847 () => fs.futimesSync(fd, new Date(), new Date()), 848 validateError 849 ); 850 }); 851} 852