diff --git a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp index 4c52cb93f0..58eb683b49 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp @@ -267,6 +267,64 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr entries, u32 return CELL_OK; } +s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, vm::ptr nread) +{ + cellFs.Log("cellFsReadWithOffset(fd=0x%x, offset=0x%llx, buf=*0x%x, buffer_size=0x%llx, nread=*0x%x)", fd, offset, buf, buffer_size, nread); + + // TODO: use single sys_fs_fcntl syscall + + std::shared_ptr file; + + if (!Emu.GetIdManager().GetIDData(fd, file)) + { + return CELL_FS_EBADF; + } + + const auto old_position = file->Tell(); + + file->Seek(offset); + + const auto read = file->Read(buf.get_ptr(), buffer_size); + + file->Seek(old_position); + + if (nread) + { + *nread = read; + } + + return CELL_OK; +} + +s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 data_size, vm::ptr nwrite) +{ + cellFs.Log("cellFsWriteWithOffset(fd=0x%x, offset=0x%llx, buf=*0x%x, data_size=0x%llx, nwrite=*0x%x)", fd, offset, buf, data_size, nwrite); + + // TODO: use single sys_fs_fcntl syscall + + std::shared_ptr file; + + if (!Emu.GetIdManager().GetIDData(fd, file)) + { + return CELL_FS_EBADF; + } + + const auto old_position = file->Tell(); + + file->Seek(offset); + + const auto written = file->Write(buf.get_ptr(), data_size); + + file->Seek(old_position); + + if (nwrite) + { + *nwrite = written; + } + + return CELL_OK; +} + s32 cellFsStReadInit(u32 fd, vm::ptr ringbuf) { cellFs.Warning("cellFsStReadInit(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf); @@ -687,24 +745,6 @@ s32 cellFsAioFinish(vm::ptr mount_point) return CELL_OK; } -s32 cellFsReadWithOffset(PPUThread& CPU, u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, vm::ptr nread) -{ - cellFs.Warning("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf=*0x%x, buffer_size=%lld, nread=*0x%llx)", fd, offset, buf, buffer_size, nread); - - int ret; - vm::stackvar> oldPos(CPU), newPos(CPU); - ret = cellFsLseek(fd, 0, CELL_FS_SEEK_CUR, oldPos); // Save the current position - if (ret) return ret; - ret = cellFsLseek(fd, offset, CELL_FS_SEEK_SET, newPos); // Move to the specified offset - if (ret) return ret; - ret = cellFsRead(CPU, fd, buf, buffer_size, nread); // Read the file - if (ret) return ret; - ret = cellFsLseek(fd, oldPos.value(), CELL_FS_SEEK_SET, newPos); // Return to the old position - if (ret) return ret; - - return CELL_OK; -} - s32 cellFsSetDefaultContainer(u32 id, u32 total_limit) { cellFs.Todo("cellFsSetDefaultContainer(id=%d, total_limit=%d)", id, total_limit); @@ -757,6 +797,7 @@ Module cellFs("cellFs", []() REG_FUNC(cellFs, cellFsGetBlockSize); REG_FUNC(cellFs, cellFsGetFreeSize); REG_FUNC(cellFs, cellFsReadWithOffset); + REG_FUNC(cellFs, cellFsWriteWithOffset); REG_FUNC(cellFs, cellFsGetDirectoryEntries); REG_FUNC(cellFs, cellFsStReadInit); REG_FUNC(cellFs, cellFsStReadFinish); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp index 165940c6d2..e17505e4ce 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp @@ -44,27 +44,17 @@ s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, } case CELL_FS_O_WRONLY: + case CELL_FS_O_RDWR: { - file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsWriteAppend)); - - if (file) - { - file->Seek(0); - } - + file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsReadWrite)); break; } case CELL_FS_O_WRONLY | CELL_FS_O_CREAT: + case CELL_FS_O_RDWR | CELL_FS_O_CREAT: { Emu.GetVFS().CreateFile(path.get_ptr()); - file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsWriteAppend)); - - if (file) - { - file->Seek(0); - } - + file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsReadWrite)); break; } @@ -87,6 +77,12 @@ s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, break; } + case CELL_FS_O_WRONLY | CELL_FS_O_TRUNC: + { + file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsWrite)); + break; + } + case CELL_FS_O_WRONLY | CELL_FS_O_CREAT | CELL_FS_O_TRUNC: { Emu.GetVFS().CreateFile(path.get_ptr()); @@ -100,19 +96,6 @@ s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsWriteAppend)); break; } - - case CELL_FS_O_RDWR: - { - file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsReadWrite)); - break; - } - - case CELL_FS_O_RDWR | CELL_FS_O_CREAT: - { - Emu.GetVFS().CreateFile(path.get_ptr()); - file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsReadWrite)); - break; - } case CELL_FS_O_RDWR | CELL_FS_O_CREAT | CELL_FS_O_TRUNC: { @@ -166,6 +149,8 @@ s32 sys_fs_write(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrit return CELL_FS_EBADF; // TODO: return if not opened for writing } + // TODO: return CELL_FS_EBUSY if locked + *nwrite = file->Write(buf.get_ptr(), nbytes); return CELL_OK; @@ -182,10 +167,7 @@ s32 sys_fs_close(u32 fd) return CELL_FS_EBADF; } - if (false) - { - return CELL_FS_EBUSY; // TODO: return if locked - } + // TODO: return CELL_FS_EBUSY if locked Emu.GetIdManager().RemoveID(fd);