IOS: Make file creation + open more concise

Creating a file then opening it in read write mode is a pretty common
operation. This commit adds a helper function that makes it easier
to read and clearer.
This commit is contained in:
Léo Lam 2018-05-08 13:05:56 +02:00
parent 90f869e940
commit 71afe6b4a6
7 changed files with 35 additions and 23 deletions

View File

@ -623,10 +623,9 @@ static s32 WriteTmdForDiVerify(FS::FileSystem* fs, const IOS::ES::TMDReader& tmd
{
const std::string temp_path = "/tmp/title.tmd";
fs->Delete(PID_KERNEL, PID_KERNEL, temp_path);
fs->CreateFile(PID_KERNEL, PID_KERNEL, temp_path, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite,
FS::Mode::None);
{
const auto file = fs->OpenFile(PID_KERNEL, PID_KERNEL, temp_path, FS::Mode::Write);
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, temp_path, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::None);
if (!file)
return FS::ConvertResult(file.Error());
if (!file->Write(tmd.GetBytes().data(), tmd.GetBytes().size()))
@ -880,7 +879,8 @@ ReturnCode ES::WriteNewCertToStore(const IOS::ES::CertReader& cert)
// Otherwise, write the new cert at the end of the store.
const auto store_file =
m_ios.GetFS()->OpenFile(PID_KERNEL, PID_KERNEL, CERT_STORE_PATH, FS::Mode::ReadWrite);
m_ios.GetFS()->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, CERT_STORE_PATH, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::Read);
if (!store_file || !store_file->Seek(0, FS::SeekMode::End) ||
!store_file->Write(cert.GetBytes().data(), cert.GetBytes().size()))
{

View File

@ -558,13 +558,11 @@ bool SharedContentMap::WriteEntries() const
{
// Temporary files are only 12 characters long and must match the final file name
const std::string temp_path = "/tmp/content.map";
m_fs->CreateFile(HLE::PID_KERNEL, HLE::PID_KERNEL, temp_path, 0, HLE::FS::Mode::ReadWrite,
HLE::FS::Mode::ReadWrite, HLE::FS::Mode::None);
// Atomically write the new content map.
{
const auto file =
m_fs->OpenFile(HLE::PID_KERNEL, HLE::PID_KERNEL, temp_path, HLE::FS::Mode::Write);
const auto file = m_fs->CreateAndOpenFile(HLE::PID_KERNEL, HLE::PID_KERNEL, temp_path,
HLE::FS::Mode::ReadWrite, HLE::FS::Mode::ReadWrite,
HLE::FS::Mode::None);
if (!file || !file->Write(m_entries.data(), m_entries.size()))
return false;
}
@ -637,8 +635,9 @@ u32 UIDSys::GetOrInsertUIDForTitle(const u64 title_id)
const u64 swapped_title_id = Common::swap64(title_id);
const u32 swapped_uid = Common::swap32(uid);
const auto file =
m_fs->OpenFile(HLE::PID_KERNEL, HLE::PID_KERNEL, UID_MAP_PATH, HLE::FS::Mode::ReadWrite);
const auto file = m_fs->CreateAndOpenFile(HLE::PID_KERNEL, HLE::PID_KERNEL, UID_MAP_PATH,
HLE::FS::Mode::ReadWrite, HLE::FS::Mode::ReadWrite,
HLE::FS::Mode::None);
if (!file || !file->Seek(0, HLE::FS::SeekMode::End) || !file->Write(&swapped_title_id, 1) ||
!file->Write(&swapped_uid, 1))
{

View File

@ -312,9 +312,8 @@ bool ES::WriteImportTMD(const IOS::ES::TMDReader& tmd)
const auto fs = m_ios.GetFS();
const std::string tmd_path = "/tmp/title.tmd";
{
fs->CreateFile(PID_KERNEL, PID_KERNEL, tmd_path, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite,
FS::Mode::None);
const auto file = fs->OpenFile(PID_KERNEL, PID_KERNEL, tmd_path, FS::Mode::Write);
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, tmd_path, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::None);
if (!file || !file->Write(tmd.GetBytes().data(), tmd.GetBytes().size()))
return false;
}

View File

@ -34,10 +34,9 @@ static ReturnCode WriteTicket(FS::FileSystem* fs, const IOS::ES::TicketReader& t
const std::string path = Common::GetTicketFileName(title_id);
fs->CreateFullPath(PID_KERNEL, PID_KERNEL, path, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite,
FS::Mode::None);
fs->CreateFile(PID_KERNEL, PID_KERNEL, path, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite,
FS::Mode::None);
const auto file = fs->OpenFile(PID_KERNEL, PID_KERNEL, path, FS::Mode::Write);
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, path, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::None);
if (!file)
return FS::ConvertResult(file.Error());
@ -387,10 +386,9 @@ ReturnCode ES::ImportContentEnd(Context& context, u32 content_fd)
const std::string temp_path =
"/tmp/" + content_path.substr(content_path.find_last_of('/') + 1, std::string::npos);
fs->CreateFile(PID_KERNEL, PID_KERNEL, temp_path, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite,
FS::Mode::None);
{
const auto file = fs->OpenFile(PID_KERNEL, PID_KERNEL, temp_path, FS::Mode::Write);
const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, temp_path, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::None);
if (!file || !file->Write(decrypted_data.data(), content_info.size))
{
ERROR_LOG(IOS_ES, "ImportContentEnd: Failed to write to %s", temp_path.c_str());

View File

@ -72,6 +72,20 @@ void FileSystem::Init()
CreateDirectory(0, 0, "/tmp", 0, Mode::ReadWrite, Mode::ReadWrite, Mode::ReadWrite);
}
Result<FileHandle> FileSystem::CreateAndOpenFile(Uid uid, Gid gid, const std::string& path,
Mode owner_mode, Mode group_mode, Mode other_mode)
{
Result<FileHandle> file = OpenFile(uid, gid, path, Mode::ReadWrite);
if (file.Succeeded())
return file;
const ResultCode result = CreateFile(uid, gid, path, 0, owner_mode, group_mode, other_mode);
if (result != ResultCode::Success)
return result;
return OpenFile(uid, gid, path, Mode::ReadWrite);
}
ResultCode FileSystem::CreateFullPath(Uid uid, Gid gid, const std::string& path,
FileAttribute attribute, Mode owner, Mode group, Mode other)
{

View File

@ -141,6 +141,9 @@ public:
/// Get a file descriptor for accessing a file. The FD will be automatically closed after use.
virtual Result<FileHandle> OpenFile(Uid uid, Gid gid, const std::string& path, Mode mode) = 0;
/// Create a file if it doesn't exist and open it in read/write mode.
Result<FileHandle> CreateAndOpenFile(Uid uid, Gid gid, const std::string& path, Mode owner_mode,
Mode group_mode, Mode other_mode);
/// Close a file descriptor.
virtual ResultCode Close(Fd fd) = 0;
/// Read `size` bytes from the file descriptor. Returns the number of bytes read.

View File

@ -37,9 +37,8 @@ void WiiNetConfig::WriteConfig(FS::FileSystem* fs) const
{
fs->CreateFullPath(PID_NCD, PID_NCD, CONFIG_PATH, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite,
FS::Mode::ReadWrite);
fs->CreateFile(PID_NCD, PID_NCD, CONFIG_PATH, 0, FS::Mode::ReadWrite, FS::Mode::ReadWrite,
FS::Mode::ReadWrite);
const auto file = fs->OpenFile(PID_NCD, PID_NCD, CONFIG_PATH, FS::Mode::Write);
const auto file = fs->CreateAndOpenFile(PID_NCD, PID_NCD, CONFIG_PATH, FS::Mode::ReadWrite,
FS::Mode::ReadWrite, FS::Mode::ReadWrite);
if (!file || !file->Write(&m_data, 1))
ERROR_LOG(IOS_NET, "Failed to write config");
}