1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 20:22:30 +01:00

fs:: handle negative seek

This commit is contained in:
Nekotekina 2017-03-23 21:32:59 +03:00
parent e12a708036
commit 0393c7f52c
4 changed files with 77 additions and 19 deletions

View File

@ -797,7 +797,11 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
whence == seek_end ? FILE_END :
(fmt::throw_exception("Invalid whence (0x%x)" HERE, whence), 0);
verify("file::seek" HERE), SetFilePointerEx(m_handle, pos, &pos, mode);
if (!SetFilePointerEx(m_handle, pos, &pos, mode))
{
g_tls_error = to_error(GetLastError());
return -1;
}
return pos.QuadPart;
}
@ -899,7 +903,12 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
(fmt::throw_exception("Invalid whence (0x%x)" HERE, whence), 0);
const auto result = ::lseek(m_fd, offset, mode);
verify("file::seek" HERE), result != -1;
if (result == -1)
{
g_tls_error = to_error(errno);
return -1;
}
return result;
}
@ -966,11 +975,20 @@ fs::file::file(const void* ptr, std::size_t size)
u64 seek(s64 offset, fs::seek_mode whence) override
{
return
whence == fs::seek_set ? m_pos = offset :
whence == fs::seek_cur ? m_pos = offset + m_pos :
whence == fs::seek_end ? m_pos = offset + m_size :
const s64 new_pos =
whence == fs::seek_set ? offset :
whence == fs::seek_cur ? offset + m_pos :
whence == fs::seek_end ? offset + size() :
(fmt::raw_error("fs::file::memory_stream::seek(): invalid whence"), 0);
if (new_pos < 0)
{
fs::g_tls_error = fs::error::inval;
return -1;
}
m_pos = new_pos;
return m_pos;
}
u64 size() override
@ -1313,6 +1331,7 @@ void fmt_class_string<fs::error>::format(std::string& out, u64 arg)
case fs::error::inval: return "Invalid arguments";
case fs::error::noent: return "Not found";
case fs::error::exist: return "Already exists";
case fs::error::acces: return "Access violation";
}
return unknown;

View File

@ -547,11 +547,20 @@ namespace fs
u64 seek(s64 offset, seek_mode whence) override
{
return
whence == fs::seek_set ? pos = offset :
whence == fs::seek_cur ? pos = offset + pos :
whence == fs::seek_end ? pos = offset + size() :
const s64 new_pos =
whence == fs::seek_set ? offset :
whence == fs::seek_cur ? offset + pos :
whence == fs::seek_end ? offset + size() :
(fmt::raw_error("fs::container_stream<>::seek(): invalid whence"), 0);
if (new_pos < 0)
{
fs::g_tls_error = fs::error::inval;
return -1;
}
pos = new_pos;
return pos;
}
u64 size() override

View File

@ -109,11 +109,20 @@ public:
u64 seek(s64 offset, fs::seek_mode whence) override
{
return
whence == fs::seek_set ? pos = offset :
whence == fs::seek_cur ? pos = offset + pos :
whence == fs::seek_end ? pos = offset + size() :
const s64 new_pos =
whence == fs::seek_set ? offset :
whence == fs::seek_cur ? offset + pos :
whence == fs::seek_end ? offset + size() :
(fmt::raw_error("EDATADecrypter::seek(): invalid whence"), 0);
if (new_pos < 0)
{
fs::g_tls_error = fs::error::inval;
return -1;
}
pos = new_pos;
return pos;
}
u64 size() override { return file_size; }
};

View File

@ -124,11 +124,20 @@ struct lv2_file::file_view : fs::file_base
u64 seek(s64 offset, fs::seek_mode whence) override
{
return
whence == fs::seek_set ? m_pos = offset :
whence == fs::seek_cur ? m_pos = offset + m_pos :
whence == fs::seek_end ? m_pos = offset + size() :
const s64 new_pos =
whence == fs::seek_set ? offset :
whence == fs::seek_cur ? offset + m_pos :
whence == fs::seek_end ? offset + size() :
(fmt::raw_error("lv2_file::file_view::seek(): invalid whence"), 0);
if (new_pos < 0)
{
fs::g_tls_error = fs::error::inval;
return -1;
}
m_pos = new_pos;
return m_pos;
}
u64 size() override
@ -694,8 +703,20 @@ error_code sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr<u64> pos)
std::lock_guard<std::mutex> lock(file->mp->mutex);
*pos = file->file.seek(offset, static_cast<fs::seek_mode>(whence));
const u64 result = file->file.seek(offset, static_cast<fs::seek_mode>(whence));
if (result == -1)
{
switch (auto error = fs::g_tls_error)
{
case fs::error::inval: return CELL_EINVAL;
default: sys_fs.error("sys_fs_lseek(): unknown error %s", error);
}
return CELL_EIO; // ???
}
*pos = result;
return CELL_OK;
}