1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

Update cellFsGetDirectoryEntries to use wait flag correctly

This commit is contained in:
Eladash 2022-10-13 18:18:24 +03:00 committed by Ivan
parent 806acf8cd0
commit a5cc9a5517
2 changed files with 48 additions and 20 deletions

View File

@ -132,7 +132,11 @@ error_code sys_event_flag_wait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode, vm
~store_result() noexcept ~store_result() noexcept
{ {
if (ptr) *ptr = val; if (ptr)
{
cpu_thread::get_current()->check_state();
*ptr = val;
}
} }
} store{result}; } store{result};
@ -254,7 +258,6 @@ error_code sys_event_flag_wait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode, vm
} }
} }
ppu.check_state();
store.val = ppu.gpr[6]; store.val = ppu.gpr[6];
return not_an_error(ppu.gpr[3]); return not_an_error(ppu.gpr[3]);
} }
@ -265,7 +268,21 @@ error_code sys_event_flag_trywait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode,
sys_event_flag.trace("sys_event_flag_trywait(id=0x%x, bitptn=0x%llx, mode=0x%x, result=*0x%x)", id, bitptn, mode, result); sys_event_flag.trace("sys_event_flag_trywait(id=0x%x, bitptn=0x%llx, mode=0x%x, result=*0x%x)", id, bitptn, mode, result);
if (result) *result = 0; // Always set result
struct store_result
{
vm::ptr<u64> ptr;
u64 val = 0;
~store_result() noexcept
{
if (ptr)
{
cpu_thread::get_current()->check_state();
*ptr = val;
}
}
} store{result};
if (!lv2_event_flag::check_mode(mode)) if (!lv2_event_flag::check_mode(mode))
{ {
@ -273,7 +290,7 @@ error_code sys_event_flag_trywait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode,
return CELL_EINVAL; return CELL_EINVAL;
} }
u64 pattern; u64 pattern{};
const auto flag = idm::check<lv2_obj, lv2_event_flag>(id, [&](lv2_event_flag& flag) const auto flag = idm::check<lv2_obj, lv2_event_flag>(id, [&](lv2_event_flag& flag)
{ {
@ -293,9 +310,7 @@ error_code sys_event_flag_trywait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode,
return not_an_error(CELL_EBUSY); return not_an_error(CELL_EBUSY);
} }
ppu.check_state(); store.val = pattern;
if (result) *result = pattern;
return CELL_OK; return CELL_OK;
} }

View File

@ -883,11 +883,12 @@ error_code sys_fs_read(ppu_thread& ppu, u32 fd, vm::ptr<void> buf, u64 nbytes, v
return CELL_EBUSY; return CELL_EBUSY;
} }
ppu.check_state();
*nread = 0; *nread = 0;
return CELL_OK; return CELL_OK;
} }
std::lock_guard lock(file->mp->mutex); std::unique_lock lock(file->mp->mutex);
if (!file->file) if (!file->file)
{ {
@ -901,10 +902,13 @@ error_code sys_fs_read(ppu_thread& ppu, u32 fd, vm::ptr<void> buf, u64 nbytes, v
} }
const u64 read_bytes = file->op_read(buf, nbytes); const u64 read_bytes = file->op_read(buf, nbytes);
const bool failure = !read_bytes && file->file.pos() < file->file.size();
lock.unlock();
ppu.check_state();
*nread = read_bytes; *nread = read_bytes;
if (!read_bytes && file->file.pos() < file->file.size()) if (failure)
{ {
// EDATA corruption perhaps // EDATA corruption perhaps
return CELL_EFSSPECIFIC; return CELL_EFSSPECIFIC;
@ -948,6 +952,7 @@ error_code sys_fs_write(ppu_thread& ppu, u32 fd, vm::cptr<void> buf, u64 nbytes,
return CELL_EBUSY; return CELL_EBUSY;
} }
ppu.check_state();
*nwrite = 0; *nwrite = 0;
return CELL_OK; return CELL_OK;
} }
@ -2197,18 +2202,28 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr<void> _arg, u32
return CELL_EBADF; return CELL_EBADF;
} }
arg->_size = 0; // This write is not really useful for cellFs but do it anyways ppu.check_state();
u32 read_count = 0;
// NOTE: This function is actually capable of reading only one entry at a time // NOTE: This function is actually capable of reading only one entry at a time
if (arg->max) if (const u32 max = arg->max)
{ {
std::memset(arg->ptr.get_ptr(), 0, arg->max * arg->ptr.size()); const auto arg_ptr = +arg->ptr;
if (auto* info = directory->dir_read()) if (auto* info = directory->dir_read())
{ {
auto& entry = arg->ptr[arg->_size++]; auto& entry = arg_ptr[read_count++];
entry.attribute.mode = info->is_directory ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666; s32 mode = info->is_directory ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666;
if (directory->mp->flags & lv2_mp_flag::read_only)
{
// Remove write permissions
mode &= ~0222;
}
entry.attribute.mode = mode;
entry.attribute.uid = directory->mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0; entry.attribute.uid = directory->mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0;
entry.attribute.gid = directory->mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0; entry.attribute.gid = directory->mp->flags & lv2_mp_flag::no_uid_gid ? -1 : 0;
entry.attribute.atime = info->atime; entry.attribute.atime = info->atime;
@ -2217,18 +2232,16 @@ error_code sys_fs_fcntl(ppu_thread& ppu, u32 fd, u32 op, vm::ptr<void> _arg, u32
entry.attribute.size = info->size; entry.attribute.size = info->size;
entry.attribute.blksize = directory->mp->block_size; entry.attribute.blksize = directory->mp->block_size;
if (directory->mp->flags & lv2_mp_flag::read_only)
{
// Remove write permissions
entry.attribute.mode &= ~0222;
}
entry.entry_name.d_type = info->is_directory ? CELL_FS_TYPE_DIRECTORY : CELL_FS_TYPE_REGULAR; entry.entry_name.d_type = info->is_directory ? CELL_FS_TYPE_DIRECTORY : CELL_FS_TYPE_REGULAR;
entry.entry_name.d_namlen = u8(std::min<usz>(info->name.size(), CELL_FS_MAX_FS_FILE_NAME_LENGTH)); entry.entry_name.d_namlen = u8(std::min<usz>(info->name.size(), CELL_FS_MAX_FS_FILE_NAME_LENGTH));
strcpy_trunc(entry.entry_name.d_name, info->name); strcpy_trunc(entry.entry_name.d_name, info->name);
} }
// Apparently all this function does to additional buffer elements is to zeroize them
std::memset(arg_ptr.get_ptr() + read_count, 0, (max - read_count) * arg->ptr.size());
} }
arg->_size = read_count;
arg->_code = CELL_OK; arg->_code = CELL_OK;
return CELL_OK; return CELL_OK;
} }