Merge pull request #4914 from MarcZX100/codex/carry-link-follow-symlink-4026
fix(libkernel_sys): follow symbolic links in link
This commit is contained in:
commit
f40b6930ff
|
|
@ -363,13 +363,13 @@ int APS5_VABI link_nid_postfix(const char* existing, const char* created) {
|
|||
if (const int error = ResolvePathError_nid_no_patch(existing, source)) return static_cast<int>(Fail(error));
|
||||
if (const int error = ResolvePathError_nid_no_patch(created, destination)) return static_cast<int>(Fail(error));
|
||||
std::error_code error;
|
||||
const auto status = std::filesystem::symlink_status(source, error);
|
||||
const auto status = std::filesystem::status(source, error);
|
||||
if (!std::filesystem::exists(status)) return static_cast<int>(Fail(GuestEnoent));
|
||||
if (std::filesystem::is_symlink(status)) throw std::runtime_error("link: a symbolic link as the existing path is not supported");
|
||||
if (std::filesystem::is_directory(status)) return static_cast<int>(Fail(GuestEperm));
|
||||
if (std::filesystem::exists(std::filesystem::symlink_status(destination, error))) return static_cast<int>(Fail(GuestEexist));
|
||||
if (!std::filesystem::is_directory(destination.parent_path(), error)) return static_cast<int>(Fail(GuestEnoent));
|
||||
std::filesystem::create_hard_link(source, destination, error);
|
||||
const auto target = std::filesystem::is_symlink(source, error) ? std::filesystem::canonical(source, error) : source;
|
||||
if (!error) std::filesystem::create_hard_link(target, destination, error);
|
||||
if (error == std::errc::cross_device_link) return static_cast<int>(Fail(GuestExdev));
|
||||
if (error) throw std::system_error(error, "link");
|
||||
RecordWrittenPath_nid_no_patch(destination);
|
||||
|
|
|
|||
|
|
@ -465,6 +465,20 @@ int main() {
|
|||
Require(fchmodat_nid_postfix(base, longName.c_str(), 0600, 0) == -1 && Error() == 63);
|
||||
#endif
|
||||
Require(sceKernelClose(base) == 0);
|
||||
#ifndef _WIN32
|
||||
if (created == 0) {
|
||||
const auto throughLink = (root / "through-link.bin").string();
|
||||
Require(link_nid_postfix(symbolic.c_str(), throughLink.c_str()) == 0);
|
||||
Require(!std::filesystem::is_symlink(std::filesystem::symlink_status(throughLink)));
|
||||
Require(std::filesystem::equivalent(throughLink, original) && std::filesystem::hard_link_count(original) == 2);
|
||||
Require(std::filesystem::remove(throughLink) && std::filesystem::hard_link_count(original) == 1);
|
||||
Require(link_nid_postfix((root / "dangling").string().c_str(), throughLink.c_str()) == -1 && Error() == 2);
|
||||
const auto directoryLink = (root / "directory-link").string();
|
||||
Require(symlink_nid_postfix(".", directoryLink.c_str()) == 0);
|
||||
Require(link_nid_postfix(directoryLink.c_str(), throughLink.c_str()) == -1 && Error() == 1);
|
||||
Require(!std::filesystem::exists(std::filesystem::symlink_status(throughLink)));
|
||||
}
|
||||
#endif
|
||||
std::filesystem::remove_all(root);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue