mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-04-29 23:41:12 -06:00
sys_fs: Fix O_CREATE and O_TRUNC for BDVD
This commit is contained in:
parent
3cca094d2d
commit
1ca8ab393a
@ -861,7 +861,7 @@ error_code sys_fs_test(ppu_thread&, u32 arg1, u32 arg2, vm::ptr<u32> arg3, u32 a
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s32 flags, s32 /*mode*/, lv2_file_type type, const lv2_fs_mount_info& mp)
|
||||
lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s32 flags, bool has_write_access, lv2_file_type type, const lv2_fs_mount_info& mp)
|
||||
{
|
||||
// TODO: other checks for path
|
||||
|
||||
@ -888,7 +888,7 @@ lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s3
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & CELL_FS_O_CREAT)
|
||||
if (flags & CELL_FS_O_CREAT && !mp.read_only)
|
||||
{
|
||||
open_mode += fs::create;
|
||||
|
||||
@ -898,7 +898,7 @@ lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s3
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & CELL_FS_O_TRUNC)
|
||||
if (flags & CELL_FS_O_TRUNC && !mp.read_only)
|
||||
{
|
||||
open_mode += fs::trunc;
|
||||
}
|
||||
@ -906,6 +906,7 @@ lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s3
|
||||
if (flags & CELL_FS_O_MSELF)
|
||||
{
|
||||
open_mode = fs::read;
|
||||
|
||||
// mself can be mself or mself | rdonly
|
||||
if (flags & ~(CELL_FS_O_MSELF | CELL_FS_O_RDONLY))
|
||||
{
|
||||
@ -918,7 +919,7 @@ lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s3
|
||||
sys_fs.warning("lv2_file::open() called with CELL_FS_O_UNK flag enabled. FLAGS: %#o", flags);
|
||||
}
|
||||
|
||||
if (mp.read_only)
|
||||
if (mp.read_only || !has_write_access)
|
||||
{
|
||||
// Deactivate mutating flags on read-only FS
|
||||
open_mode = fs::read;
|
||||
@ -970,12 +971,12 @@ lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s3
|
||||
|
||||
if (!file)
|
||||
{
|
||||
if (mp.read_only)
|
||||
if (mp.read_only || !has_write_access)
|
||||
{
|
||||
// Failed to create file on read-only FS (file doesn't exist)
|
||||
if (flags & CELL_FS_O_ACCMODE && flags & CELL_FS_O_CREAT)
|
||||
if (flags & CELL_FS_O_CREAT)
|
||||
{
|
||||
return {CELL_EPERM};
|
||||
return {mp.read_only ? CELL_EPERM : CELL_EACCES};
|
||||
}
|
||||
}
|
||||
|
||||
@ -988,6 +989,7 @@ lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s3
|
||||
{
|
||||
case fs::error::notdir: return {CELL_ENOTDIR};
|
||||
case fs::error::noent: return {CELL_ENOENT};
|
||||
case fs::error::isdir: return {CELL_EISDIR};
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
@ -1000,6 +1002,11 @@ lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s3
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & CELL_FS_O_TRUNC && (mp.read_only || !has_write_access))
|
||||
{
|
||||
return {mp.read_only ? CELL_EPERM : CELL_EACCES};
|
||||
}
|
||||
|
||||
if (flags & CELL_FS_O_MSELF && !verify_mself(file))
|
||||
{
|
||||
return {CELL_ENOTMSELF};
|
||||
@ -1113,11 +1120,6 @@ lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mo
|
||||
return {CELL_ENOTMOUNTED, path};
|
||||
}
|
||||
|
||||
if (flags & CELL_FS_O_CREAT && !has_fs_write_rights(vpath) && !fs::is_dir(local_path))
|
||||
{
|
||||
return {CELL_EACCES};
|
||||
}
|
||||
|
||||
lv2_file_type type = lv2_file_type::regular;
|
||||
|
||||
if (size == 8)
|
||||
@ -1132,7 +1134,7 @@ lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mo
|
||||
}
|
||||
}
|
||||
|
||||
auto [error, file] = open_raw(local_path, flags, mode, type, mp);
|
||||
auto [error, file] = open_raw(local_path, flags, has_fs_write_rights(vpath), type, mp);
|
||||
|
||||
return {.error = error, .ppath = std::move(path), .real_path = std::move(local_path), .file = std::move(file), .type = type};
|
||||
}
|
||||
@ -1823,13 +1825,13 @@ error_code sys_fs_mkdir(ppu_thread& ppu, vm::cptr<char> path, s32 mode)
|
||||
return {CELL_EROFS, path};
|
||||
}
|
||||
|
||||
std::lock_guard lock(mp->mutex);
|
||||
|
||||
if (!fs::exists(local_path) && !has_fs_write_rights(path.get_ptr()))
|
||||
{
|
||||
return {CELL_EACCES, path};
|
||||
}
|
||||
|
||||
std::lock_guard lock(mp->mutex);
|
||||
|
||||
if (!fs::create_dir(local_path))
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
@ -1953,26 +1955,26 @@ error_code sys_fs_rmdir(ppu_thread& ppu, vm::cptr<char> path)
|
||||
|
||||
if (mp == &g_mp_sys_dev_root)
|
||||
{
|
||||
return {CELL_EPERM, path};
|
||||
return {CELL_EPERM, vpath};
|
||||
}
|
||||
|
||||
if (local_path.empty())
|
||||
{
|
||||
return {CELL_ENOTMOUNTED, path};
|
||||
return {CELL_ENOTMOUNTED, vpath};
|
||||
}
|
||||
|
||||
if (mp.read_only)
|
||||
{
|
||||
return {CELL_EROFS, path};
|
||||
}
|
||||
|
||||
if (fs::is_dir(local_path) && !has_fs_write_rights(path.get_ptr()))
|
||||
{
|
||||
return {CELL_EACCES};
|
||||
return {CELL_EROFS, vpath};
|
||||
}
|
||||
|
||||
std::lock_guard lock(mp->mutex);
|
||||
|
||||
if (fs::is_dir(local_path) && !has_fs_write_rights(vpath))
|
||||
{
|
||||
return {CELL_EACCES, vpath};
|
||||
}
|
||||
|
||||
if (!fs::remove_dir(local_path))
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
@ -1984,7 +1986,7 @@ error_code sys_fs_rmdir(ppu_thread& ppu, vm::cptr<char> path)
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
return { CELL_ENOTDIR, vpath };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
@ -1992,7 +1994,7 @@ error_code sys_fs_rmdir(ppu_thread& ppu, vm::cptr<char> path)
|
||||
}
|
||||
}
|
||||
|
||||
sys_fs.notice("sys_fs_rmdir(): directory %s removed", path);
|
||||
sys_fs.notice("sys_fs_rmdir(): directory %s removed", vpath);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -341,7 +341,7 @@ struct lv2_file final : lv2_fs_object
|
||||
};
|
||||
|
||||
// Open a file with wrapped logic of sys_fs_open
|
||||
static open_raw_result_t open_raw(const std::string& path, s32 flags, s32 mode, lv2_file_type type = lv2_file_type::regular, const lv2_fs_mount_info& mp = g_mi_sys_not_found);
|
||||
static open_raw_result_t open_raw(const std::string& path, s32 flags, bool has_write_access, lv2_file_type type = lv2_file_type::regular, const lv2_fs_mount_info& mp = g_mi_sys_not_found);
|
||||
static open_result_t open(std::string_view vpath, s32 flags, s32 mode, const void* arg = {}, u64 size = 0);
|
||||
|
||||
// File reading with intermediate buffer
|
||||
|
||||
@ -1028,7 +1028,7 @@ bool vfs::host::rename(const std::string& from, const std::string& to, const lv2
|
||||
}
|
||||
|
||||
// Reopen with ignored TRUNC, APPEND, CREATE and EXCL flags
|
||||
auto res0 = lv2_file::open_raw(file.real_path, file.flags & CELL_FS_O_ACCMODE, file.mode, file.type, file.mp);
|
||||
auto res0 = lv2_file::open_raw(file.real_path, file.flags & CELL_FS_O_ACCMODE, true, file.type, file.mp);
|
||||
file.file = std::move(res0.file);
|
||||
ensure(file.file.operator bool());
|
||||
file.file.seek(file.restore_data.seek_pos);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user