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} /deny "everyone:(OI)(CI)(DE,DC,AD,WD)"`); 30 } else { 31 fs.chmodSync(dir, '444'); 32 } 33 return accessErrorCode; 34} 35 36function makeDirectoryWritable(dir) { 37 if (common.isWindows) { 38 execSync(`icacls ${dir} /remove:d "everyone"`); 39 } 40} 41 42// Synchronous API should return an EACCESS error with path populated. 43{ 44 const dir = path.join(tmpdir.path, `mkdirp_${n++}`); 45 fs.mkdirSync(dir); 46 const codeExpected = makeDirectoryReadOnly(dir); 47 let err = null; 48 try { 49 fs.mkdirSync(path.join(dir, '/foo'), { recursive: true }); 50 } catch (_err) { 51 err = _err; 52 } 53 makeDirectoryWritable(dir); 54 assert(err); 55 assert.strictEqual(err.code, codeExpected); 56 assert(err.path); 57} 58 59// Asynchronous API should return an EACCESS error with path populated. 60{ 61 const dir = path.join(tmpdir.path, `mkdirp_${n++}`); 62 fs.mkdirSync(dir); 63 const codeExpected = makeDirectoryReadOnly(dir); 64 fs.mkdir(path.join(dir, '/bar'), { recursive: true }, (err) => { 65 makeDirectoryWritable(dir); 66 assert(err); 67 assert.strictEqual(err.code, codeExpected); 68 assert(err.path); 69 }); 70} 71