fs: fix rmSync error code

Return the correct error code, when a directory_not_empty error
occurred.

Fixes: https://github.com/nodejs/node/issues/57095
PR-URL: https://github.com/nodejs/node/pull/57103
Reviewed-By: Jason Zhang <xzha4350@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
Paul Schwabauer 2025-02-25 22:13:03 +01:00 committed by GitHub
parent c864dea910
commit f52a358217
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 5 deletions

View File

@ -1705,7 +1705,8 @@ static void RmSync(const FunctionCallbackInfo<Value>& args) {
return env->ThrowErrnoException(EPERM, "rm", message.c_str(), path_c_str);
} else if (error == std::errc::directory_not_empty) {
std::string message = "Directory not empty: " + file_path_str;
return env->ThrowErrnoException(EACCES, "rm", message.c_str(), path_c_str);
return env->ThrowErrnoException(
ENOTEMPTY, "rm", message.c_str(), path_c_str);
} else if (error == std::errc::not_a_directory) {
std::string message = "Not a directory: " + file_path_str;
return env->ThrowErrnoException(ENOTDIR, "rm", message.c_str(), path_c_str);

View File

@ -481,12 +481,20 @@ if (isGitPresent) {
// IBMi has a different access permission mechanism
// This test should not be run as `root`
if (!common.isIBMi && (common.isWindows || process.getuid() !== 0)) {
function makeDirectoryReadOnly(dir, mode) {
function makeDirectoryReadOnly(dir, allowExecute) {
let accessErrorCode = 'EACCES';
if (common.isMacOS && allowExecute) {
accessErrorCode = 'ENOTEMPTY';
}
if (common.isWindows) {
accessErrorCode = 'EPERM';
execSync(`icacls ${dir} /deny "everyone:(OI)(CI)(DE,DC)"`);
const permissions = ['DE', 'DC'];
if (!allowExecute) {
permissions.push('X');
}
execSync(`icacls ${dir} /deny "everyone:(OI)(CI)(${permissions.join(',')})"`);
} else {
const mode = allowExecute ? 0o555 : 0o444;
fs.chmodSync(dir, mode);
}
return accessErrorCode;
@ -510,7 +518,7 @@ if (isGitPresent) {
try {
fs.mkdirSync(dirname, common.mustNotMutateObjectDeep({ recursive: true }));
fs.writeFileSync(filePath, 'hello');
const code = makeDirectoryReadOnly(dirname, 0o444);
const code = makeDirectoryReadOnly(dirname, false);
assert.throws(() => {
fs.rmSync(filePath, common.mustNotMutateObjectDeep({ force: true }));
}, {
@ -532,7 +540,7 @@ if (isGitPresent) {
fs.mkdirSync(middle);
fs.mkdirSync(path.join(middle, 'leaf')); // Make `middle` non-empty
try {
const code = makeDirectoryReadOnly(middle, 0o555);
const code = makeDirectoryReadOnly(middle, true);
try {
assert.throws(() => {
fs.rmSync(root, common.mustNotMutateObjectDeep({ recursive: true }));