mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-01 15:02:40 +00:00
Accurate directory handling in open
Directories can be opened, and can be created in open, these changes should handle that more accurately.
This commit is contained in:
parent
83926f90eb
commit
4118b5f87f
@ -94,33 +94,57 @@ s32 PS4_SYSV_ABI open(const char* raw_path, s32 flags, u16 mode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file->m_guest_name = path;
|
||||||
|
file->m_host_name = mnt->GetHostPath(file->m_guest_name);
|
||||||
|
bool exists = std::filesystem::exists(file->m_host_name);
|
||||||
|
s32 e = 0;
|
||||||
|
|
||||||
if (directory) {
|
if (directory) {
|
||||||
file->type = Core::FileSys::FileType::Directory;
|
file->type = Core::FileSys::FileType::Directory;
|
||||||
file->m_guest_name = path;
|
|
||||||
file->m_host_name = mnt->GetHostPath(file->m_guest_name);
|
if (create) {
|
||||||
if (!std::filesystem::is_directory(file->m_host_name)) { // directory doesn't exist
|
if (excl && exists) {
|
||||||
|
// Error if file exists
|
||||||
|
h->DeleteHandle(handle);
|
||||||
|
*__Error() = POSIX_EEXIST;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!std::filesystem::create_directory(file->m_host_name)) {
|
||||||
|
// Directory creation failed
|
||||||
|
*__Error() = POSIX_EIO;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (!exists) {
|
||||||
|
// File to open doesn't exist, return ENOENT
|
||||||
h->DeleteHandle(handle);
|
h->DeleteHandle(handle);
|
||||||
*__Error() = POSIX_ENOENT;
|
*__Error() = POSIX_ENOENT;
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read) {
|
||||||
|
e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Read);
|
||||||
|
} else if (write || rdwr || append || truncate) {
|
||||||
|
// Cannot open directories with any type of write access
|
||||||
|
h->DeleteHandle(handle);
|
||||||
|
*__Error() = POSIX_EISDIR;
|
||||||
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
if (create) {
|
// Invalid flags
|
||||||
return handle; // dir already exists
|
*__Error() = POSIX_EINVAL;
|
||||||
} else {
|
return -1;
|
||||||
mnt->IterateDirectory(file->m_guest_name,
|
}
|
||||||
[&file](const auto& ent_path, const auto ent_is_file) {
|
|
||||||
auto& dir_entry = file->dirents.emplace_back();
|
// If opening is a success, iterate through contents
|
||||||
dir_entry.name = ent_path.filename().string();
|
if (e == 0) {
|
||||||
dir_entry.isFile = ent_is_file;
|
mnt->IterateDirectory(file->m_guest_name,
|
||||||
});
|
[&file](const auto& ent_path, const auto ent_is_file) {
|
||||||
file->dirents_index = 0;
|
auto& dir_entry = file->dirents.emplace_back();
|
||||||
}
|
dir_entry.name = ent_path.filename().string();
|
||||||
|
dir_entry.isFile = ent_is_file;
|
||||||
|
});
|
||||||
|
file->dirents_index = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
file->m_guest_name = path;
|
|
||||||
file->m_host_name = mnt->GetHostPath(file->m_guest_name);
|
|
||||||
bool exists = std::filesystem::exists(file->m_host_name);
|
|
||||||
int e = 0;
|
|
||||||
|
|
||||||
if (create) {
|
if (create) {
|
||||||
if (excl && exists) {
|
if (excl && exists) {
|
||||||
// Error if file exists
|
// Error if file exists
|
||||||
@ -140,20 +164,15 @@ s32 PS4_SYSV_ABI open(const char* raw_path, s32 flags, u16 mode) {
|
|||||||
if (read) {
|
if (read) {
|
||||||
// Read only
|
// Read only
|
||||||
e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Read);
|
e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Read);
|
||||||
|
} else if (append) {
|
||||||
|
// Append can be specified with rdwr or write, but we treat it as a separate mode.
|
||||||
|
e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Append);
|
||||||
} else if (write) {
|
} else if (write) {
|
||||||
// Write only
|
// Write only
|
||||||
if (append) {
|
e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Write);
|
||||||
e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Append);
|
|
||||||
} else {
|
|
||||||
e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Write);
|
|
||||||
}
|
|
||||||
} else if (rdwr) {
|
} else if (rdwr) {
|
||||||
// Read and write
|
// Read and write
|
||||||
if (append) {
|
e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::ReadWrite);
|
||||||
e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::Append);
|
|
||||||
} else {
|
|
||||||
e = file->f.Open(file->m_host_name, Common::FS::FileAccessMode::ReadWrite);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Invalid flags
|
// Invalid flags
|
||||||
*__Error() = POSIX_EINVAL;
|
*__Error() = POSIX_EINVAL;
|
||||||
@ -164,14 +183,15 @@ s32 PS4_SYSV_ABI open(const char* raw_path, s32 flags, u16 mode) {
|
|||||||
// If the file was opened successfully and truncate was enabled, reduce size to 0
|
// If the file was opened successfully and truncate was enabled, reduce size to 0
|
||||||
file->f.SetSize(0);
|
file->f.SetSize(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e != 0) {
|
|
||||||
// Open failed in platform-specific code, errno needs to be converted.
|
|
||||||
h->DeleteHandle(handle);
|
|
||||||
SetPosixErrno(e);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e != 0) {
|
||||||
|
// Open failed in platform-specific code, errno needs to be converted.
|
||||||
|
h->DeleteHandle(handle);
|
||||||
|
SetPosixErrno(e);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
file->is_opened = true;
|
file->is_opened = true;
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user