fix(libkernel): accept a trailing slash in sceKernelMkdir
sceKernelMkdir checked that the parent of the resolved path exists, but for "dir/" std::filesystem::path reports "dir" itself as the parent, so the call failed with ENOENT and created nothing, while FreeBSD's mkdir (and the POSIX mkdir export) accept it. Strip trailing separators first, and report ENOTDIR when the parent exists but is not a directory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 5f74ddba8b346e6c552cf02554d47382708206f3)
This commit is contained in:
parent
57f96fd2b3
commit
3779ffa375
|
|
@ -544,10 +544,13 @@ int APS5_VABI getdents_nid_postfix(int fd, char* buf, int nbytes) {
|
|||
int APS5_VABI sceKernelMkdir(const char* path, uint16_t mode) {
|
||||
(void)mode;
|
||||
if (path == nullptr) throw std::invalid_argument("sceKernelMkdir: path is null");
|
||||
const auto native = ResolvePath_nid_no_patch(path);
|
||||
auto native = ResolvePath_nid_no_patch(path);
|
||||
while (!native.has_filename() && native.has_relative_path()) native = native.parent_path();
|
||||
std::error_code error;
|
||||
if (std::filesystem::exists(native, error)) return SceErrorFromErrno(GUEST_EEXIST);
|
||||
if (!std::filesystem::exists(native.parent_path(), error)) return SceErrorFromErrno(GUEST_ENOENT);
|
||||
const auto parent = std::filesystem::status(native.parent_path(), error);
|
||||
if (!std::filesystem::exists(parent)) return SceErrorFromErrno(GUEST_ENOENT);
|
||||
if (!std::filesystem::is_directory(parent)) return SceErrorFromErrno(GUEST_ENOTDIR);
|
||||
if (!std::filesystem::create_directory(native, error)) return SceErrorFromErrno(error.value() ? error.value() : GUEST_EIO);
|
||||
RecordWrittenPath_nid_no_patch(native);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@ int main() {
|
|||
Require(sceKernelMkdir("kernel_sync_probe", 0777) == 0);
|
||||
Require(Recorded("kernel_sync_probe"));
|
||||
std::ofstream("kernel_sync_probe/existing.bin") << "existing";
|
||||
Require(sceKernelMkdir("kernel_sync_probe/nested/", 0777) == 0);
|
||||
Require(std::filesystem::is_directory("kernel_sync_probe/nested") && Recorded("kernel_sync_probe/nested"));
|
||||
Require(sceKernelMkdir("kernel_sync_probe/nested/", 0777) == static_cast<int>(0x80020011u));
|
||||
Require(sceKernelMkdir("kernel_sync_probe/existing.bin/child", 0777) == static_cast<int>(0x80020014u));
|
||||
const int reader = sceKernelOpen("kernel_sync_probe/existing.bin", 0x0, 0);
|
||||
Require(reader >= 0 && sceKernelClose(reader) == 0);
|
||||
void* stream = fopen_nid_postfix("kernel_sync_probe/existing.bin", "r");
|
||||
|
|
|
|||
Loading…
Reference in New Issue