1'use strict'; 2 3// Test that mkdir with recursive option returns appropriate error 4// when executed on folder it does not have permission to access. 5// Ref: https://github.com/nodejs/node/issues/31481 6 7const common = require('../common'); 8 9if (!common.isWindows && process.getuid() === 0) 10 common.skip('as this test should not be run as `root`'); 11 12if (common.isIBMi) 13 common.skip('IBMi has a different access permission mechanism'); 14 15const tmpdir = require('../common/tmpdir'); 16tmpdir.refresh(); 17 18const assert = require('assert'); 19const { execSync } = require('child_process'); 20const fs = require('fs'); 21const path = require('path'); 22 23let n = 0; 24 25function makeDirectoryReadOnly(dir) { 26 let accessErrorCode = 'EACCES'; 27 if (common.isWindows) { 28 accessErrorCode = 'EPERM'; 29 execSync(`icacls ${dir} /inheritance:r`); 30 execSync(`icacls ${dir} /deny "everyone":W`); 31 } else { 32 fs.chmodSync(dir, '444'); 33 } 34 return accessErrorCode; 35} 36 37function makeDirectoryWritable(dir) { 38 if (common.isWindows) { 39 execSync(`icacls ${dir} /grant "everyone":W`); 40 } 41} 42 43// Synchronous API should return an EACCESS error with path populated. 44{ 45 const dir = path.join(tmpdir.path, `mkdirp_${n++}`); 46 fs.mkdirSync(dir); 47 const codeExpected = makeDirectoryReadOnly(dir); 48 let err = null; 49 try { 50 fs.mkdirSync(path.join(dir, '/foo'), { recursive: true }); 51 } catch (_err) { 52 err = _err; 53 } 54 makeDirectoryWritable(dir); 55 assert(err); 56 assert.strictEqual(err.code, codeExpected); 57 assert(err.path); 58} 59 60// Asynchronous API should return an EACCESS error with path populated. 61{ 62 const dir = path.join(tmpdir.path, `mkdirp_${n++}`); 63 fs.mkdirSync(dir); 64 const codeExpected = makeDirectoryReadOnly(dir); 65 fs.mkdir(path.join(dir, '/bar'), { recursive: true }, (err) => { 66 makeDirectoryWritable(dir); 67 assert(err); 68 assert.strictEqual(err.code, codeExpected); 69 assert(err.path); 70 }); 71} 72