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:
Nekotekina 2015-04-19 20:14:16 +03:00
parent 93ebce4162
commit 3c872ab611
9 changed files with 68 additions and 54 deletions

View file

@ -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_function_enable = Ini.DBGAutoPauseFunctionCall.GetValue();
initialized = true;
@ -123,4 +120,4 @@ void AutoPause::TryPause(u32 code) {
}
}
}
}
}

View file

@ -395,8 +395,8 @@ bool rfile_t::open(const std::string& filename, u32 mode)
switch (mode & (o_read | o_write))
{
case o_read: flags |= O_READ; break;
case o_write: flags |= O_WRITE; break;
case o_read: flags |= O_RDONLY; break;
case o_write: flags |= O_WRONLY; break;
case o_read | o_write: flags |= O_RDWR; break;
default:
{
@ -476,7 +476,7 @@ u64 rfile_t::read(void* buffer, u64 count) const
return nread;
#else
return read64(fd, buffer, count);
return ::read(fd, buffer, count);
#endif
}
@ -491,7 +491,7 @@ u64 rfile_t::write(const void* buffer, u64 count) const
return nwritten;
#else
return write64(fd, buffer, count);
return ::write(fd, buffer, count);
#endif
}

View file

@ -6,7 +6,6 @@
#include "Ini.h"
#include "Emu/System.h"
#include "Utilities/Log.h"
#include <sys/stat.h> // To check whether directory exists
#undef CreateFile
#undef CopyFile
@ -496,33 +495,30 @@ void VFS::SaveLoadDevices(std::vector<VFSManagerEntry>& res, bool is_load)
entries_count.SaveValue(count);
}
// Custom EmulationDir.
// TODO:: should have a better log that would show results before loading a game?
// Custom EmulationDir
if (Ini.SysEmulationDirPathEnable.GetValue())
{
std::string EmulationDir = Ini.SysEmulationDirPath.GetValue();
if (EmulationDir.empty())
Ini.SysEmulationDirPath.SetValue(Emu.GetEmulatorPath());
struct stat fstatinfo;
if ((stat(EmulationDir.c_str(), &fstatinfo)))
std::string dir = Ini.SysEmulationDirPath.GetValue();
if (dir.empty())
{
LOG_NOTICE(GENERAL, "Custom EmualtionDir: Tried %s but it doesn't exists. Maybe you add some not needed chars like '\"'?");
Ini.SysEmulationDirPathEnable.SetValue(false);
Ini.SysEmulationDirPath.SetValue(Emu.GetEmulatorPath());
}
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
{
// If that is not directory turn back to use original one.
LOG_NOTICE(GENERAL, "Custom EmulationDir: Cause path %s is not a valid directory.", EmulationDir);
Ini.SysEmulationDirPathEnable.SetValue(false);
LOG_NOTICE(GENERAL, "Custom EmulationDir: $(EmulatorDir) bound to '%s'", dir);
}
}
// 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)
{

View file

@ -30,4 +30,9 @@ public:
std::string GetPath() const;
u32 GetOpenMode() const;
virtual bool IsOpened() const override
{
return !m_path.empty();
}
};

View file

@ -45,7 +45,7 @@ u64 vfsLocalFile::Tell() const
bool vfsLocalFile::IsOpened() const
{
return m_file /*&& vfsFileBase::IsOpened()*/;
return m_file && vfsFileBase::IsOpened();
}
bool vfsLocalFile::Exists(const std::string& path)

View file

@ -24,4 +24,9 @@ public:
virtual u64 Tell() const override;
virtual bool IsOpened() const override;
virtual const rfile_t& GetFile() const
{
return m_file;
}
};

View file

@ -518,38 +518,38 @@ __noinline s32 savedata_op(
break;
}
std::string filepath;
std::string file_path;
switch (const u32 type = fileSet->fileType)
{
case CELL_SAVEDATA_FILETYPE_SECUREFILE:
case CELL_SAVEDATA_FILETYPE_NORMALFILE:
{
filepath = fileSet->fileName.get_ptr();
file_path = fileSet->fileName.get_ptr();
break;
}
case CELL_SAVEDATA_FILETYPE_CONTENT_ICON0:
{
filepath = "ICON0.PNG";
file_path = "ICON0.PNG";
break;
}
case CELL_SAVEDATA_FILETYPE_CONTENT_ICON1:
{
filepath = "ICON1.PAM";
file_path = "ICON1.PAM";
break;
}
case CELL_SAVEDATA_FILETYPE_CONTENT_PIC1:
{
filepath = "PIC1.PNG";
file_path = "PIC1.PNG";
break;
}
case CELL_SAVEDATA_FILETYPE_CONTENT_SND0:
{
filepath = "SND0.AT3";
file_path = "SND0.AT3";
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)
{
case CELL_SAVEDATA_FILEOP_READ:
{
file.reset(Emu.GetVFS().OpenFile(filepath, o_read));
file->Seek(fileSet->fileOffset);
fileGet->excSize = file->Read(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize));
rfile_t file(local_path, o_read);
file.seek(fileSet->fileOffset);
fileGet->excSize = static_cast<u32>(file.read(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize)));
break;
}
case CELL_SAVEDATA_FILEOP_WRITE:
{
file.reset(Emu.GetVFS().OpenFile(filepath, o_write | o_create));
file->Seek(fileSet->fileOffset);
fileGet->excSize = file->Write(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize));
// TODO: truncate this fucked shit
rfile_t file(local_path, o_write | o_create);
file.seek(fileSet->fileOffset);
fileGet->excSize = static_cast<u32>(file.write(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize)));
file.trunc(file.seek(0, from_cur)); // truncate
break;
}
case CELL_SAVEDATA_FILEOP_DELETE:
{
Emu.GetVFS().RemoveFile(filepath);
rRemoveFile(local_path);
fileGet->excSize = 0;
break;
}
case CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC:
{
file.reset(Emu.GetVFS().OpenFile(filepath, o_write | o_create));
file->Seek(fileSet->fileOffset);
fileGet->excSize = file->Write(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize));
rfile_t file(local_path, o_write | o_create);
file.seek(fileSet->fileOffset);
fileGet->excSize = static_cast<u32>(file.write(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize)));
break;
}

View file

@ -14,6 +14,7 @@
#include "Emu/FS/VFS.h"
#include "Emu/FS/vfsFile.h"
#include "Emu/FS/vfsLocalFile.h"
#include "Emu/FS/vfsDir.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)
{
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);
if (!file)
if (!file || !(file->flags & CELL_FS_O_ACCMODE))
{
return CELL_FS_EBADF;
}
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;
}

View file

@ -40,7 +40,6 @@
#include <map>
#include <unordered_map>
#include <sys/stat.h>
#include "Utilities/GNU.h"
typedef unsigned int uint;