mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 14:01:25 +12:00
sys_fs_ftruncate implemented, bugfixes
Eliminated using stat() for _WIN32 because it doesn't support unicode correctly, use rExists() or get_file_info() instead
This commit is contained in:
parent
93ebce4162
commit
3c872ab611
9 changed files with 68 additions and 54 deletions
|
@ -77,10 +77,7 @@ void AutoPause::Reload(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_WARNING(HLE, "No pause.bin found, Auto Pause will not work.");
|
|
||||||
}
|
|
||||||
m_pause_syscall_enable = Ini.DBGAutoPauseSystemCall.GetValue();
|
m_pause_syscall_enable = Ini.DBGAutoPauseSystemCall.GetValue();
|
||||||
m_pause_function_enable = Ini.DBGAutoPauseFunctionCall.GetValue();
|
m_pause_function_enable = Ini.DBGAutoPauseFunctionCall.GetValue();
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
|
@ -395,8 +395,8 @@ bool rfile_t::open(const std::string& filename, u32 mode)
|
||||||
|
|
||||||
switch (mode & (o_read | o_write))
|
switch (mode & (o_read | o_write))
|
||||||
{
|
{
|
||||||
case o_read: flags |= O_READ; break;
|
case o_read: flags |= O_RDONLY; break;
|
||||||
case o_write: flags |= O_WRITE; break;
|
case o_write: flags |= O_WRONLY; break;
|
||||||
case o_read | o_write: flags |= O_RDWR; break;
|
case o_read | o_write: flags |= O_RDWR; break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
@ -476,7 +476,7 @@ u64 rfile_t::read(void* buffer, u64 count) const
|
||||||
|
|
||||||
return nread;
|
return nread;
|
||||||
#else
|
#else
|
||||||
return read64(fd, buffer, count);
|
return ::read(fd, buffer, count);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,7 +491,7 @@ u64 rfile_t::write(const void* buffer, u64 count) const
|
||||||
|
|
||||||
return nwritten;
|
return nwritten;
|
||||||
#else
|
#else
|
||||||
return write64(fd, buffer, count);
|
return ::write(fd, buffer, count);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "Ini.h"
|
#include "Ini.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
#include "Utilities/Log.h"
|
#include "Utilities/Log.h"
|
||||||
#include <sys/stat.h> // To check whether directory exists
|
|
||||||
|
|
||||||
#undef CreateFile
|
#undef CreateFile
|
||||||
#undef CopyFile
|
#undef CopyFile
|
||||||
|
@ -496,33 +495,30 @@ void VFS::SaveLoadDevices(std::vector<VFSManagerEntry>& res, bool is_load)
|
||||||
entries_count.SaveValue(count);
|
entries_count.SaveValue(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom EmulationDir.
|
// Custom EmulationDir
|
||||||
// TODO:: should have a better log that would show results before loading a game?
|
|
||||||
if (Ini.SysEmulationDirPathEnable.GetValue())
|
if (Ini.SysEmulationDirPathEnable.GetValue())
|
||||||
{
|
{
|
||||||
std::string EmulationDir = Ini.SysEmulationDirPath.GetValue();
|
std::string dir = Ini.SysEmulationDirPath.GetValue();
|
||||||
if (EmulationDir.empty())
|
|
||||||
Ini.SysEmulationDirPath.SetValue(Emu.GetEmulatorPath());
|
if (dir.empty())
|
||||||
struct stat fstatinfo;
|
|
||||||
if ((stat(EmulationDir.c_str(), &fstatinfo)))
|
|
||||||
{
|
{
|
||||||
LOG_NOTICE(GENERAL, "Custom EmualtionDir: Tried %s but it doesn't exists. Maybe you add some not needed chars like '\"'?");
|
Ini.SysEmulationDirPath.SetValue(Emu.GetEmulatorPath());
|
||||||
Ini.SysEmulationDirPathEnable.SetValue(false);
|
}
|
||||||
|
|
||||||
|
FileInfo info;
|
||||||
|
if (!get_file_info(dir, info) || !info.exists)
|
||||||
|
{
|
||||||
|
LOG_ERROR(GENERAL, "Custom EmulationDir: '%s' not found", dir);
|
||||||
|
}
|
||||||
|
else if (!info.isDirectory)
|
||||||
|
{
|
||||||
|
LOG_ERROR(GENERAL, "Custom EmulationDir: '%s' is not a valid directory", dir);
|
||||||
}
|
}
|
||||||
else if (fstatinfo.st_mode & S_IFDIR)
|
|
||||||
LOG_NOTICE(GENERAL, "Custom EmualtionDir: On, Binded $(EmulatorDir) to %s.", EmulationDir);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If that is not directory turn back to use original one.
|
LOG_NOTICE(GENERAL, "Custom EmulationDir: $(EmulatorDir) bound to '%s'", dir);
|
||||||
LOG_NOTICE(GENERAL, "Custom EmulationDir: Cause path %s is not a valid directory.", EmulationDir);
|
|
||||||
Ini.SysEmulationDirPathEnable.SetValue(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// I left this to check again just to catch those failed in directory checks.
|
|
||||||
if (!Ini.SysEmulationDirPathEnable.GetValue())
|
|
||||||
{
|
|
||||||
LOG_NOTICE(GENERAL, "Custom EmualtionDir: Off, Binded $(EmulatorDir) to %s.", Emu.GetEmulatorPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i=0; i<count; ++i)
|
for(int i=0; i<count; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,4 +30,9 @@ public:
|
||||||
|
|
||||||
std::string GetPath() const;
|
std::string GetPath() const;
|
||||||
u32 GetOpenMode() const;
|
u32 GetOpenMode() const;
|
||||||
|
|
||||||
|
virtual bool IsOpened() const override
|
||||||
|
{
|
||||||
|
return !m_path.empty();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,7 +45,7 @@ u64 vfsLocalFile::Tell() const
|
||||||
|
|
||||||
bool vfsLocalFile::IsOpened() const
|
bool vfsLocalFile::IsOpened() const
|
||||||
{
|
{
|
||||||
return m_file /*&& vfsFileBase::IsOpened()*/;
|
return m_file && vfsFileBase::IsOpened();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool vfsLocalFile::Exists(const std::string& path)
|
bool vfsLocalFile::Exists(const std::string& path)
|
||||||
|
|
|
@ -24,4 +24,9 @@ public:
|
||||||
virtual u64 Tell() const override;
|
virtual u64 Tell() const override;
|
||||||
|
|
||||||
virtual bool IsOpened() const override;
|
virtual bool IsOpened() const override;
|
||||||
|
|
||||||
|
virtual const rfile_t& GetFile() const
|
||||||
|
{
|
||||||
|
return m_file;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -518,38 +518,38 @@ __noinline s32 savedata_op(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string filepath;
|
std::string file_path;
|
||||||
|
|
||||||
switch (const u32 type = fileSet->fileType)
|
switch (const u32 type = fileSet->fileType)
|
||||||
{
|
{
|
||||||
case CELL_SAVEDATA_FILETYPE_SECUREFILE:
|
case CELL_SAVEDATA_FILETYPE_SECUREFILE:
|
||||||
case CELL_SAVEDATA_FILETYPE_NORMALFILE:
|
case CELL_SAVEDATA_FILETYPE_NORMALFILE:
|
||||||
{
|
{
|
||||||
filepath = fileSet->fileName.get_ptr();
|
file_path = fileSet->fileName.get_ptr();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CELL_SAVEDATA_FILETYPE_CONTENT_ICON0:
|
case CELL_SAVEDATA_FILETYPE_CONTENT_ICON0:
|
||||||
{
|
{
|
||||||
filepath = "ICON0.PNG";
|
file_path = "ICON0.PNG";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CELL_SAVEDATA_FILETYPE_CONTENT_ICON1:
|
case CELL_SAVEDATA_FILETYPE_CONTENT_ICON1:
|
||||||
{
|
{
|
||||||
filepath = "ICON1.PAM";
|
file_path = "ICON1.PAM";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CELL_SAVEDATA_FILETYPE_CONTENT_PIC1:
|
case CELL_SAVEDATA_FILETYPE_CONTENT_PIC1:
|
||||||
{
|
{
|
||||||
filepath = "PIC1.PNG";
|
file_path = "PIC1.PNG";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CELL_SAVEDATA_FILETYPE_CONTENT_SND0:
|
case CELL_SAVEDATA_FILETYPE_CONTENT_SND0:
|
||||||
{
|
{
|
||||||
filepath = "SND0.AT3";
|
file_path = "SND0.AT3";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,43 +560,43 @@ __noinline s32 savedata_op(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
psf.SetInteger("*" + filepath, fileSet->fileType.data() == se32(CELL_SAVEDATA_FILETYPE_SECUREFILE));
|
psf.SetInteger("*" + file_path, fileSet->fileType.data() == se32(CELL_SAVEDATA_FILETYPE_SECUREFILE));
|
||||||
|
|
||||||
filepath = dir_path + filepath;
|
std::string local_path;
|
||||||
|
|
||||||
std::unique_ptr<vfsStream> file;
|
Emu.GetVFS().GetDevice(dir_path + file_path, local_path);
|
||||||
|
|
||||||
switch (const u32 op = fileSet->fileOperation)
|
switch (const u32 op = fileSet->fileOperation)
|
||||||
{
|
{
|
||||||
case CELL_SAVEDATA_FILEOP_READ:
|
case CELL_SAVEDATA_FILEOP_READ:
|
||||||
{
|
{
|
||||||
file.reset(Emu.GetVFS().OpenFile(filepath, o_read));
|
rfile_t file(local_path, o_read);
|
||||||
file->Seek(fileSet->fileOffset);
|
file.seek(fileSet->fileOffset);
|
||||||
fileGet->excSize = file->Read(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize));
|
fileGet->excSize = static_cast<u32>(file.read(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CELL_SAVEDATA_FILEOP_WRITE:
|
case CELL_SAVEDATA_FILEOP_WRITE:
|
||||||
{
|
{
|
||||||
file.reset(Emu.GetVFS().OpenFile(filepath, o_write | o_create));
|
rfile_t file(local_path, o_write | o_create);
|
||||||
file->Seek(fileSet->fileOffset);
|
file.seek(fileSet->fileOffset);
|
||||||
fileGet->excSize = file->Write(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize));
|
fileGet->excSize = static_cast<u32>(file.write(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize)));
|
||||||
// TODO: truncate this fucked shit
|
file.trunc(file.seek(0, from_cur)); // truncate
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CELL_SAVEDATA_FILEOP_DELETE:
|
case CELL_SAVEDATA_FILEOP_DELETE:
|
||||||
{
|
{
|
||||||
Emu.GetVFS().RemoveFile(filepath);
|
rRemoveFile(local_path);
|
||||||
fileGet->excSize = 0;
|
fileGet->excSize = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC:
|
case CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC:
|
||||||
{
|
{
|
||||||
file.reset(Emu.GetVFS().OpenFile(filepath, o_write | o_create));
|
rfile_t file(local_path, o_write | o_create);
|
||||||
file->Seek(fileSet->fileOffset);
|
file.seek(fileSet->fileOffset);
|
||||||
fileGet->excSize = file->Write(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize));
|
fileGet->excSize = static_cast<u32>(file.write(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "Emu/FS/VFS.h"
|
#include "Emu/FS/VFS.h"
|
||||||
#include "Emu/FS/vfsFile.h"
|
#include "Emu/FS/vfsFile.h"
|
||||||
|
#include "Emu/FS/vfsLocalFile.h"
|
||||||
#include "Emu/FS/vfsDir.h"
|
#include "Emu/FS/vfsDir.h"
|
||||||
|
|
||||||
#include "sys_fs.h"
|
#include "sys_fs.h"
|
||||||
|
@ -471,18 +472,29 @@ s32 sys_fs_truncate(vm::ptr<const char> path, u64 size)
|
||||||
|
|
||||||
s32 sys_fs_ftruncate(u32 fd, u64 size)
|
s32 sys_fs_ftruncate(u32 fd, u64 size)
|
||||||
{
|
{
|
||||||
sys_fs.Todo("sys_fs_ftruncate(fd=0x%x, size=0x%llx)", fd, size);
|
sys_fs.Warning("sys_fs_ftruncate(fd=0x%x, size=0x%llx)", fd, size);
|
||||||
|
|
||||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(fd);
|
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(fd);
|
||||||
|
|
||||||
if (!file)
|
if (!file || !(file->flags & CELL_FS_O_ACCMODE))
|
||||||
{
|
{
|
||||||
return CELL_FS_EBADF;
|
return CELL_FS_EBADF;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(file->mutex);
|
std::lock_guard<std::mutex> lock(file->mutex);
|
||||||
|
|
||||||
// must use rfile_t::trunc()
|
const auto local_file = dynamic_cast<vfsLocalFile*>(file->file.get());
|
||||||
|
|
||||||
|
if (!local_file)
|
||||||
|
{
|
||||||
|
sys_fs.Error("sys_fs_ftruncate(fd=0x%x): not a local file");
|
||||||
|
return CELL_FS_ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!local_file->GetFile().trunc(size))
|
||||||
|
{
|
||||||
|
return CELL_FS_EIO; // ???
|
||||||
|
}
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include "Utilities/GNU.h"
|
#include "Utilities/GNU.h"
|
||||||
|
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue