mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-15 11:18:36 +12:00
Implement vfs::host::unlink
Emulate POSIX behaviour in sys_fs_unlink. This should allow to delete opened files transparently on Windows.
This commit is contained in:
parent
0736fc8b28
commit
40142420c1
3 changed files with 43 additions and 1 deletions
|
@ -852,7 +852,7 @@ error_code sys_fs_unlink(vm::cptr<char> path)
|
||||||
return {CELL_ENOTMOUNTED, path};
|
return {CELL_ENOTMOUNTED, path};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fs::remove_file(local_path))
|
if (!vfs::host::unlink(local_path))
|
||||||
{
|
{
|
||||||
switch (auto error = fs::g_tls_error)
|
switch (auto error = fs::g_tls_error)
|
||||||
{
|
{
|
||||||
|
|
|
@ -385,6 +385,17 @@ std::string vfs::unescape(std::string_view path)
|
||||||
result += '*';
|
result += '*';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case char{u8"$"[2]}:
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
// Special case: filename starts with full-width $ likely created by vfs::host::unlink
|
||||||
|
result.resize(1, '.');
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[fallthrough]];
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// Unrecognized character (ignored)
|
// Unrecognized character (ignored)
|
||||||
|
@ -462,3 +473,31 @@ bool vfs::host::rename(const std::string& from, const std::string& to, bool over
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool vfs::host::unlink(const std::string& path)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (path.size() < 2 || reinterpret_cast<const u16&>(path.front()) != "//"_u16)
|
||||||
|
{
|
||||||
|
// Rename to special dummy name which will be ignored by VFS (but opened file handles can still read or write it)
|
||||||
|
const std::string dummy = fmt::format(u8"%s/$%s%s", fs::get_parent_dir(path), fmt::base57(std::hash<std::string>()(path)), fmt::base57(__rdtsc()));
|
||||||
|
|
||||||
|
if (!fs::rename(path, dummy, true))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs::file f{dummy, fs::read + fs::write})
|
||||||
|
{
|
||||||
|
// Set to delete on close on last handle
|
||||||
|
f.set_delete();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: what could cause this and how to handle it
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return fs::remove_file(path);
|
||||||
|
}
|
||||||
|
|
|
@ -23,5 +23,8 @@ namespace vfs
|
||||||
{
|
{
|
||||||
// Call fs::rename with retry on access error
|
// Call fs::rename with retry on access error
|
||||||
bool rename(const std::string& from, const std::string& to, bool overwrite);
|
bool rename(const std::string& from, const std::string& to, bool overwrite);
|
||||||
|
|
||||||
|
// Delete file without deleting its contents, emulated with MoveFileEx on Windows
|
||||||
|
bool unlink(const std::string&);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue