Merge pull request #4348 from milescoviello/fix/rmdir-symlink

fix(libkernel): fail rmdir on a symbolic link instead of removing it
This commit is contained in:
Dean 2026-10-13 04:53:02 +13:00 committed by GitHub
commit 3881117feb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 0 deletions

View File

@ -1085,6 +1085,7 @@ int APS5_VABI sceKernelRmdir(const char* path) {
std::filesystem::path native;
if (const int error = ResolvePathError_nid_no_patch(path, native)) return SceKernelError(error);
std::error_code error;
if (std::filesystem::is_symlink(native, error)) return SceErrorFromErrno(GUEST_ENOTDIR);
if (!std::filesystem::is_directory(native, error)) {
const bool blockedByFile = HasNonDirectoryPrefix(native) || std::filesystem::exists(WithoutTrailingSeparator(native), error);
return SceErrorFromErrno(blockedByFile ? GUEST_ENOTDIR : GUEST_ENOENT);

View File

@ -628,6 +628,20 @@ int main() {
Require(rmdir_nid_postfix((missingName + "/").c_str()) == -1 && *__error_nid_postfix() == 2);
Require(sceKernelRmdir((presentName + "/").c_str()) == static_cast<int>(0x80020014u));
Require(sceKernelRmdir((missingName + "/").c_str()) == static_cast<int>(0x80020002u));
#ifndef _WIN32
const auto linkedDirectory = root / "linked-directory";
const auto directoryLink = root / "directory-link";
const auto danglingDirectoryLink = root / "dangling-directory-link";
Require(std::filesystem::create_directory(linkedDirectory));
std::filesystem::create_directory_symlink("linked-directory", directoryLink);
std::filesystem::create_directory_symlink("missing-directory", danglingDirectoryLink);
Require(rmdir_nid_postfix(directoryLink.string().c_str()) == -1 && *__error_nid_postfix() == 20);
Require(sceKernelRmdir(directoryLink.string().c_str()) == static_cast<int>(0x80020014u));
Require(rmdir_nid_postfix(danglingDirectoryLink.string().c_str()) == -1 && *__error_nid_postfix() == 20);
Require(std::filesystem::is_symlink(directoryLink) && std::filesystem::is_directory(linkedDirectory));
Require(unlink_nid_postfix(directoryLink.string().c_str()) == 0 && unlink_nid_postfix(danglingDirectoryLink.string().c_str()) == 0);
Require(rmdir_nid_postfix(linkedDirectory.string().c_str()) == 0 && !std::filesystem::exists(linkedDirectory));
#endif
const auto dotDirectory = root / "dot-directory";
Require(std::filesystem::create_directory(dotDirectory));
const auto dotDirectoryName = dotDirectory.string() + "/.";