Try to fix some fs errors

This commit is contained in:
Nekotekina 2017-09-19 00:03:26 +03:00
parent a428dac71c
commit 5c93acefd9
3 changed files with 138 additions and 17 deletions

View File

@ -204,7 +204,7 @@ error_code sys_fs_open(vm::cptr<char> path, s32 flags, vm::ptr<u32> fd, s32 mode
// TODO: other checks for path
if (fs::is_dir(local_path))
if (local_path == "/" || fs::is_dir(local_path))
{
return {CELL_EISDIR, path};
}
@ -432,6 +432,11 @@ error_code sys_fs_opendir(vm::cptr<char> path, vm::ptr<u32> fd)
// TODO: other checks for path
if (local_path == "/")
{
return {CELL_EPERM, path};
}
if (fs::is_file(local_path))
{
return {CELL_ENOTDIR, path};
@ -508,14 +513,20 @@ error_code sys_fs_stat(vm::cptr<char> path, vm::ptr<CellFsStat> sb)
{
sys_fs.warning("sys_fs_stat(path=%s, sb=*0x%x)", path, sb);
const std::string& local_path = vfs::get(path.get_ptr());
const std::string local_path = vfs::get(path.get_ptr());
if (local_path.empty())
{
return {CELL_ENOTMOUNTED, path};
}
fs::stat_t info;
fs::stat_t info{};
if (local_path == "/")
{
sb->mode = CELL_FS_S_IFDIR | 0444;
return CELL_OK;
}
if (!fs::stat(local_path, info))
{
@ -578,7 +589,19 @@ error_code sys_fs_mkdir(vm::cptr<char> path, s32 mode)
{
sys_fs.warning("sys_fs_mkdir(path=%s, mode=%#o)", path, mode);
if (!fs::create_path(vfs::get(path.get_ptr())))
const std::string local_path = vfs::get(path.get_ptr());
if (local_path.empty())
{
return {CELL_ENOTMOUNTED, path};
}
if (local_path == "/")
{
return {CELL_EEXIST, path};
}
if (!fs::create_path(local_path))
{
switch (auto error = fs::g_tls_error)
{
@ -598,7 +621,20 @@ error_code sys_fs_rename(vm::cptr<char> from, vm::cptr<char> to)
{
sys_fs.warning("sys_fs_rename(from=%s, to=%s)", from, to);
if (!fs::rename(vfs::get(from.get_ptr()), vfs::get(to.get_ptr()), false))
const std::string local_from = vfs::get(from.get_ptr());
const std::string local_to = vfs::get(to.get_ptr());
if (local_from.empty() || local_to.empty())
{
return CELL_ENOTMOUNTED;
}
if (local_to == "/" || local_from == "/")
{
return CELL_EPERM;
}
if (!fs::rename(local_from, local_to, false))
{
switch (auto error = fs::g_tls_error)
{
@ -618,7 +654,19 @@ error_code sys_fs_rmdir(vm::cptr<char> path)
{
sys_fs.warning("sys_fs_rmdir(path=%s)", path);
if (!fs::remove_dir(vfs::get(path.get_ptr())))
const std::string local_path = vfs::get(path.get_ptr());
if (local_path.empty())
{
return {CELL_ENOTMOUNTED, path};
}
if (local_path == "/")
{
return {CELL_EPERM, path};
}
if (!fs::remove_dir(local_path))
{
switch (auto error = fs::g_tls_error)
{
@ -638,7 +686,19 @@ error_code sys_fs_unlink(vm::cptr<char> path)
{
sys_fs.warning("sys_fs_unlink(path=%s)", path);
if (!fs::remove_file(vfs::get(path.get_ptr())))
const std::string local_path = vfs::get(path.get_ptr());
if (local_path.empty())
{
return {CELL_ENOTMOUNTED, path};
}
if (local_path == "/")
{
return {CELL_EISDIR, path};
}
if (!fs::remove_file(local_path))
{
switch (auto error = fs::g_tls_error)
{
@ -768,8 +828,20 @@ error_code sys_fs_fcntl(u32 fd, u32 op, vm::ptr<void> _arg, u32 _size)
{
const auto arg = vm::static_ptr_cast<lv2_file_c0000002>(_arg);
const std::string local_path = vfs::get(arg->path.get_ptr());
if (local_path.empty())
{
return {CELL_ENOTMOUNTED, arg->path};
}
if (local_path == "/")
{
return {CELL_EPERM, arg->path};
}
fs::device_stat info;
if (!fs::statfs(vfs::get(arg->path.get_ptr()), info))
if (!fs::statfs(local_path, info))
{
switch (auto error = fs::g_tls_error)
{
@ -1127,7 +1199,19 @@ error_code sys_fs_truncate(vm::cptr<char> path, u64 size)
{
sys_fs.warning("sys_fs_truncate(path=%s, size=0x%llx)", path, size);
if (!fs::truncate_file(vfs::get(path.get_ptr()), size))
const std::string local_path = vfs::get(path.get_ptr());
if (local_path.empty())
{
return {CELL_ENOTMOUNTED, path};
}
if (local_path == "/")
{
return {CELL_EISDIR, path};
}
if (!fs::truncate_file(local_path, size))
{
switch (auto error = fs::g_tls_error)
{
@ -1207,8 +1291,20 @@ error_code sys_fs_disk_free(vm::ps3::cptr<char> path, vm::ptr<u64> total_free, v
{
sys_fs.warning("sys_fs_disk_free(path=%s total_free=*0x%x avail_free=*0x%x)", path, total_free, avail_free);
const std::string local_path = vfs::get(path.get_ptr());
if (local_path.empty())
{
return {CELL_ENOTMOUNTED, path};
}
if (local_path == "/")
{
return {CELL_EPERM, path};
}
fs::device_stat info;
if (!fs::statfs(vfs::get(path.get_ptr()), info))
if (!fs::statfs(local_path, info))
{
switch (auto error = fs::g_tls_error)
{
@ -1229,7 +1325,19 @@ error_code sys_fs_utime(vm::ps3::cptr<char> path, vm::ps3::cptr<CellFsUtimbuf> t
{
sys_fs.warning("sys_fs_utime(path=%s, timep=*0x%x)", path, timep);
if (!fs::utime(vfs::get(path.get_ptr()), timep->actime, timep->modtime))
const std::string local_path = vfs::get(path.get_ptr());
if (local_path.empty())
{
return {CELL_ENOTMOUNTED, path};
}
if (local_path == "/")
{
return {CELL_EISDIR, path};
}
if (!fs::utime(local_path, timep->actime, timep->modtime))
{
switch (auto error = fs::g_tls_error)
{

View File

@ -360,6 +360,7 @@ void Emulator::Load(bool add_only)
vfs::mount("dev_usb", fmt::replace_all(g_cfg.vfs.dev_usb000, "$(EmulatorDir)", emu_dir));
vfs::mount("dev_usb000", fmt::replace_all(g_cfg.vfs.dev_usb000, "$(EmulatorDir)", emu_dir));
vfs::mount("app_home", home_dir.empty() ? elf_dir + '/' : fmt::replace_all(home_dir, "$(EmulatorDir)", emu_dir));
vfs::mount("", elf_dir + '/');
// Detect boot location
const std::string hdd0_game = vfs::get("/dev_hdd0/game/");

View File

@ -26,24 +26,36 @@ bool vfs::mount(const std::string& dev_name, const std::string& path)
std::string vfs::get(const std::string& vpath, vfs::type _type)
{
const auto table = fxm::get_always<vfs_manager>();
reader_lock lock(table->mutex);
std::smatch match;
if (!std::regex_match(vpath, match, _type == type::ps3 ? s_regex_ps3 : s_regex_psv))
{
LOG_WARNING(GENERAL, "vfs::get(): invalid input: %s", vpath);
return{};
const auto found = table->mounted.find("");
if (found == table->mounted.end())
{
LOG_WARNING(GENERAL, "vfs::get(): no default directory: %s", vpath);
return {};
}
return found->second + vpath;
}
const auto table = fxm::get_always<vfs_manager>();
reader_lock lock(table->mutex);
if (_type == type::ps3 && match.length(1) == 0)
{
return "/";
}
const auto found = table->mounted.find(match.str(1));
if (found == table->mounted.end())
{
LOG_WARNING(GENERAL, "vfs::get(): device not found: %s", vpath);
return{};
return {};
}
// Concatenate