mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-04-02 19:07:53 -06:00
sys_fs: Implement ENOTDIR
This commit is contained in:
parent
122ccca50e
commit
bd95c728f0
@ -166,6 +166,7 @@ static fs::error to_error(int e)
|
||||
case ENOTEMPTY: return fs::error::notempty;
|
||||
case EROFS: return fs::error::readonly;
|
||||
case EISDIR: return fs::error::isdir;
|
||||
case ENOTDIR: return fs::error::notdir;
|
||||
case ENOSPC: return fs::error::nospace;
|
||||
case EXDEV: return fs::error::xdev;
|
||||
default: return fs::error::unknown;
|
||||
@ -2833,6 +2834,7 @@ void fmt_class_string<fs::error>::format(std::string& out, u64 arg)
|
||||
case fs::error::notempty: return "Not empty";
|
||||
case fs::error::readonly: return "Read only";
|
||||
case fs::error::isdir: return "Is a directory";
|
||||
case fs::error::notdir: return "Not a directory";
|
||||
case fs::error::toolong: return "Path too long";
|
||||
case fs::error::nospace: return "Not enough space on the device";
|
||||
case fs::error::xdev: return "Device mismatch";
|
||||
|
||||
@ -683,6 +683,7 @@ namespace fs
|
||||
notempty,
|
||||
readonly,
|
||||
isdir,
|
||||
notdir,
|
||||
toolong,
|
||||
nospace,
|
||||
xdev,
|
||||
|
||||
@ -140,6 +140,32 @@ bool verify_mself(const fs::file& mself_file)
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: May not be thread-safe (or even, process-safe)
|
||||
bool has_non_directory_components(std::string_view path)
|
||||
{
|
||||
std::string path0{path};
|
||||
|
||||
while (true)
|
||||
{
|
||||
const std::string sub_path = fs::get_parent_dir(path0);
|
||||
|
||||
if (sub_path.size() >= path0.size())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
fs::stat_t stat{};
|
||||
if (fs::get_stat(sub_path, stat))
|
||||
{
|
||||
return !stat.is_directory;
|
||||
}
|
||||
|
||||
path0 = std::move(sub_path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
lv2_fs_mount_info_map::lv2_fs_mount_info_map()
|
||||
{
|
||||
for (auto mp = &g_mp_sys_dev_root; mp; mp = mp->next) // Scan and keep track of pre-mounted devices
|
||||
@ -899,8 +925,17 @@ lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s3
|
||||
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir: return {CELL_ENOTDIR};
|
||||
case fs::error::noent: return {CELL_ENOENT};
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return {CELL_ENOTDIR};
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1372,6 +1407,11 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<u32> fd)
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
@ -1555,6 +1595,10 @@ error_code sys_fs_stat(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<CellFsStat>
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir:
|
||||
{
|
||||
return { CELL_ENOTDIR, path};
|
||||
}
|
||||
case fs::error::noent:
|
||||
{
|
||||
// Try to analyse split file (TODO)
|
||||
@ -1594,6 +1638,11 @@ error_code sys_fs_stat(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<CellFsStat>
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
@ -1720,6 +1769,10 @@ error_code sys_fs_mkdir(ppu_thread& ppu, vm::cptr<char> path, s32 mode)
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir:
|
||||
{
|
||||
return { CELL_ENOTDIR, path};
|
||||
}
|
||||
case fs::error::noent:
|
||||
{
|
||||
return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path};
|
||||
@ -1728,7 +1781,15 @@ error_code sys_fs_mkdir(ppu_thread& ppu, vm::cptr<char> path, s32 mode)
|
||||
{
|
||||
return {sys_fs.warning, CELL_EEXIST, path};
|
||||
}
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1789,9 +1850,18 @@ error_code sys_fs_rename(ppu_thread& ppu, vm::cptr<char> from, vm::cptr<char> to
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir: return {CELL_ENOTDIR, from};
|
||||
case fs::error::noent: return {CELL_ENOENT, from};
|
||||
case fs::error::exist: return {CELL_EEXIST, to};
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_from))
|
||||
{
|
||||
return {CELL_ENOTDIR, from};
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1842,9 +1912,18 @@ error_code sys_fs_rmdir(ppu_thread& ppu, vm::cptr<char> path)
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir: return {CELL_ENOTDIR, path};
|
||||
case fs::error::noent: return {CELL_ENOENT, path};
|
||||
case fs::error::notempty: return {CELL_ENOTEMPTY, path};
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1896,11 +1975,23 @@ error_code sys_fs_unlink(ppu_thread& ppu, vm::cptr<char> path)
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir:
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
case fs::error::noent:
|
||||
{
|
||||
return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path};
|
||||
}
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2737,7 +2828,15 @@ error_code sys_fs_get_block_size(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<u
|
||||
{
|
||||
case fs::error::exist: return {CELL_EISDIR, path};
|
||||
case fs::error::noent: return {CELL_ENOENT, path};
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2789,11 +2888,23 @@ error_code sys_fs_truncate(ppu_thread& ppu, vm::cptr<char> path, u64 size)
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir:
|
||||
{
|
||||
return { CELL_ENOTDIR, path};
|
||||
}
|
||||
case fs::error::noent:
|
||||
{
|
||||
return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path};
|
||||
}
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2840,7 +2951,10 @@ error_code sys_fs_ftruncate(ppu_thread& ppu, u32 fd, u64 size)
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::ok:
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2887,6 +3001,10 @@ error_code sys_fs_chmod(ppu_thread&, vm::cptr<char> path, s32 mode)
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir:
|
||||
{
|
||||
return { CELL_ENOTDIR, path};
|
||||
}
|
||||
case fs::error::noent:
|
||||
{
|
||||
// Try to locate split files
|
||||
@ -2900,8 +3018,12 @@ error_code sys_fs_chmod(ppu_thread&, vm::cptr<char> path, s32 mode)
|
||||
}
|
||||
default:
|
||||
{
|
||||
sys_fs.error("sys_fs_chmod(): unknown error %s", error);
|
||||
return {CELL_EIO, path};
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3033,11 +3155,23 @@ error_code sys_fs_utime(ppu_thread& ppu, vm::cptr<char> path, vm::cptr<CellFsUti
|
||||
{
|
||||
switch (auto error = fs::g_tls_error)
|
||||
{
|
||||
case fs::error::notdir:
|
||||
{
|
||||
return { CELL_ENOTDIR, path};
|
||||
}
|
||||
case fs::error::noent:
|
||||
{
|
||||
return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path};
|
||||
}
|
||||
default: fmt::throw_exception("unknown error %s", error);
|
||||
default:
|
||||
{
|
||||
if (has_non_directory_components(local_path))
|
||||
{
|
||||
return { CELL_ENOTDIR, path };
|
||||
}
|
||||
|
||||
fmt::throw_exception("unknown error %s", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -585,10 +585,8 @@ std::unique_ptr<fs::dir_base> iso_device::open_dir(const std::string& path)
|
||||
|
||||
if (!node->metadata.is_directory)
|
||||
{
|
||||
// fs::dir::open -> ::readdir should return ENOTDIR when path is
|
||||
// pointing to a file instead of a folder, which translates to error::unknown.
|
||||
// doing the same here.
|
||||
fs::g_tls_error = fs::error::unknown;
|
||||
// fs::dir::open -> ::readdir should return ENOTDIR when path is pointing to a file instead of a folder.
|
||||
fs::g_tls_error = fs::error::notdir;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user