diff --git a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp index 58eb683b49..42d876804c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp @@ -273,20 +273,20 @@ s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, // TODO: use single sys_fs_fcntl syscall - std::shared_ptr file; + std::shared_ptr file; - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!Emu.GetIdManager().GetIDData(fd, file) || file->flags & CELL_FS_O_WRONLY) { return CELL_FS_EBADF; } - const auto old_position = file->Tell(); + const auto old_position = file->file->Tell(); - file->Seek(offset); + file->file->Seek(offset); - const auto read = file->Read(buf.get_ptr(), buffer_size); + const auto read = file->file->Read(buf.get_ptr(), buffer_size); - file->Seek(old_position); + file->file->Seek(old_position); if (nread) { @@ -302,20 +302,20 @@ s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 data_ // TODO: use single sys_fs_fcntl syscall - std::shared_ptr file; + std::shared_ptr file; - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!Emu.GetIdManager().GetIDData(fd, file) || !(file->flags & CELL_FS_O_ACCMODE)) { return CELL_FS_EBADF; } - const auto old_position = file->Tell(); + const auto old_position = file->file->Tell(); - file->Seek(offset); + file->file->Seek(offset); - const auto written = file->Write(buf.get_ptr(), data_size); + const auto written = file->file->Write(buf.get_ptr(), data_size); - file->Seek(old_position); + file->file->Seek(old_position); if (nwrite) { @@ -329,7 +329,7 @@ s32 cellFsStReadInit(u32 fd, vm::ptr ringbuf) { cellFs.Warning("cellFsStReadInit(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -354,7 +354,7 @@ s32 cellFsStReadFinish(u32 fd) { cellFs.Warning("cellFsStReadFinish(fd=0x%x)", fd); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -368,7 +368,7 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr ringbuf) { cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -383,7 +383,7 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr status) { cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, status=*0x%x)", fd, status); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -396,7 +396,7 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr regid) { cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, regid=*0x%x)", fd, regid); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -409,7 +409,7 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) { cellFs.Todo("cellFsStReadStart(fd=0x%x, offset=0x%llx, size=0x%llx)", fd, offset, size); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -423,7 +423,7 @@ s32 cellFsStReadStop(u32 fd) { cellFs.Warning("cellFsStReadStop(fd=0x%x)", fd); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -436,17 +436,17 @@ s32 cellFsStRead(u32 fd, vm::ptr buf, u64 size, vm::ptr rsize) { cellFs.Warning("cellFsStRead(fd=0x%x, buf=*0x%x, size=0x%llx, rsize=*0x%x)", fd, buf, size, rsize); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; // TODO: use ringbuffer (fs_config) fs_config.m_regid += size; - if (file->Eof()) + if (file->file->Eof()) return CELL_FS_ERANGE; - *rsize = file->Read(buf.get_ptr(), size); + *rsize = file->file->Read(buf.get_ptr(), size); return CELL_OK; } @@ -455,7 +455,7 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr> addr, vm::ptr s { cellFs.Todo("cellFsStReadGetCurrentAddr(fd=0x%x, addr=*0x%x, size=*0x%x)", fd, addr, size); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -466,7 +466,7 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr addr, u64 size) { cellFs.Todo("cellFsStReadPutCurrentAddr(fd=0x%x, addr=*0x%x, size=0x%llx)", fd, addr, size); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -477,7 +477,7 @@ s32 cellFsStReadWait(u32 fd, u64 size) { cellFs.Todo("cellFsStReadWait(fd=0x%x, size=0x%llx)", fd, size); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -488,7 +488,7 @@ s32 cellFsStReadWaitCallback(u32 fd, u64 size, vm::ptr { cellFs.Todo("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=*0x%x)", fd, size, func); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -653,7 +653,7 @@ void fsAioRead(u32 fd, vm::ptr aio, int xid, vm::ptr orig_file; + std::shared_ptr orig_file; if (!Emu.GetIdManager().GetIDData(fd, orig_file)) { cellFs.Error("Wrong fd (%s)", fd); @@ -663,7 +663,7 @@ void fsAioRead(u32 fd, vm::ptr aio, int xid, vm::ptrsize; - vfsStream& file = *orig_file; + vfsStream& file = *orig_file->file; const u64 old_pos = file.Tell(); file.Seek((u64)aio->offset); @@ -702,7 +702,7 @@ s32 cellFsAioRead(vm::ptr aio, vm::ptr id, vm::ptr orig_file; + std::shared_ptr orig_file; u32 fd = aio->fd; if (!Emu.GetIdManager().GetIDData(fd, orig_file)) @@ -756,7 +756,7 @@ s32 cellFsSetIoBufferFromDefaultContainer(u32 fd, u32 buffer_size, u32 page_type { cellFs.Todo("cellFsSetIoBufferFromDefaultContainer(fd=%d, buffer_size=%d, page_type=%d)", fd, buffer_size, page_type); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp index 28d570fbfe..ce29a0f55e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp @@ -9,6 +9,7 @@ #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFileBase.h" +#include "Emu/SysCalls/lv2/sys_fs.h" #include "cellGifDec.h" @@ -44,10 +45,10 @@ int cellGifDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptr file(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)); + std::shared_ptr file(new fs_file_t(std::shared_ptr(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)), 0, 0)); if (!file) return CELL_GIFDEC_ERROR_OPEN_FILE; current_subHandle->fd = Emu.GetIdManager().GetNewID(file, TYPE_FS_FILE); - current_subHandle->fileSize = file->GetSize(); + current_subHandle->fileSize = file->file->GetSize(); break; } } @@ -82,9 +83,9 @@ int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr case se32(CELL_GIFDEC_FILE): { - auto file = Emu.GetIdManager().GetIDData(fd); - file->Seek(0); - file->Read(buffer.begin(), buffer.size()); + auto file = Emu.GetIdManager().GetIDData(fd); + file->file->Seek(0); + file->file->Read(buffer.begin(), buffer.size()); break; } } @@ -166,9 +167,9 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::pt case se32(CELL_GIFDEC_FILE): { - auto file = Emu.GetIdManager().GetIDData(fd); - file->Seek(0); - file->Read(gif.ptr(), gif.size()); + auto file = Emu.GetIdManager().GetIDData(fd); + file->file->Seek(0); + file->file->Read(gif.ptr(), gif.size()); break; } } @@ -268,7 +269,7 @@ int cellGifDecClose(u32 mainHandle, u32 subHandle) if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data)) return CELL_GIFDEC_ERROR_FATAL; - Emu.GetIdManager().RemoveID(subHandle_data->fd); + Emu.GetIdManager().RemoveID(subHandle_data->fd); Emu.GetIdManager().RemoveID(subHandle); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp index 62ac42645f..c2b58805d5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp @@ -8,6 +8,7 @@ #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFileBase.h" +#include "Emu/SysCalls/lv2/sys_fs.h" #include "cellJpgDec.h" @@ -50,10 +51,10 @@ int cellJpgDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptr file(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)); + std::shared_ptr file(new fs_file_t(std::shared_ptr(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)), 0, 0)); if (!file) return CELL_JPGDEC_ERROR_OPEN_FILE; current_subHandle->fd = Emu.GetIdManager().GetNewID(file, TYPE_FS_FILE); - current_subHandle->fileSize = file->GetSize(); + current_subHandle->fileSize = file->file->GetSize(); break; } } @@ -73,7 +74,7 @@ int cellJpgDecClose(u32 mainHandle, u32 subHandle) if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data)) return CELL_JPGDEC_ERROR_FATAL; - Emu.GetIdManager().RemoveID(subHandle_data->fd); + Emu.GetIdManager().RemoveID(subHandle_data->fd); Emu.GetIdManager().RemoveID(subHandle); return CELL_OK; @@ -102,9 +103,9 @@ int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr case se32(CELL_JPGDEC_FILE): { - auto file = Emu.GetIdManager().GetIDData(fd); - file->Seek(0); - file->Read(buffer.ptr(), buffer.size()); + auto file = Emu.GetIdManager().GetIDData(fd); + file->file->Seek(0); + file->file->Read(buffer.ptr(), buffer.size()); break; } } @@ -173,9 +174,9 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::pt case se32(CELL_JPGDEC_FILE): { - auto file = Emu.GetIdManager().GetIDData(fd); - file->Seek(0); - file->Read(jpg.ptr(), jpg.size()); + auto file = Emu.GetIdManager().GetIDData(fd); + file->file->Seek(0); + file->file->Read(jpg.ptr(), jpg.size()); break; } } diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index 2b201f20a0..b3de15a608 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -8,6 +8,7 @@ #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFileBase.h" +#include "Emu/SysCalls/lv2/sys_fs.h" #include "cellPngDec.h" @@ -81,10 +82,10 @@ s32 pngDecOpen( case se32(CELL_PNGDEC_FILE): { // Get file descriptor and size - std::shared_ptr file(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)); + std::shared_ptr file(new fs_file_t(std::shared_ptr(Emu.GetVFS().OpenFile(src->fileName.get_ptr(), vfsRead)), 0, 0)); if (!file) return CELL_PNGDEC_ERROR_OPEN_FILE; stream->fd = Emu.GetIdManager().GetNewID(file, TYPE_FS_FILE); - stream->fileSize = file->GetSize(); + stream->fileSize = file->file->GetSize(); break; } } @@ -110,7 +111,7 @@ s32 pngDecOpen( s32 pngDecClose(CellPngDecSubHandle stream) { - Emu.GetIdManager().RemoveID(stream->fd); + Emu.GetIdManager().RemoveID(stream->fd); if (!Memory.Free(stream.addr())) { @@ -143,9 +144,9 @@ s32 pngReadHeader( break; case se32(CELL_PNGDEC_FILE): { - auto file = Emu.GetIdManager().GetIDData(stream->fd); - file->Seek(0); - file->Read(buffer.begin(), buffer.size()); + auto file = Emu.GetIdManager().GetIDData(stream->fd); + file->file->Seek(0); + file->file->Read(buffer.begin(), buffer.size()); break; } } @@ -255,9 +256,9 @@ s32 pngDecodeData( case se32(CELL_PNGDEC_FILE): { - auto file = Emu.GetIdManager().GetIDData(stream->fd); - file->Seek(0); - file->Read(png.ptr(), png.size()); + auto file = Emu.GetIdManager().GetIDData(stream->fd); + file->file->Seek(0); + file->file->Read(png.ptr(), png.size()); break; } } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp index e17505e4ce..4b4a0d5ca6 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp @@ -116,8 +116,10 @@ s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, sys_fs.Error("sys_fs_open(): failed to open '%s' (flags=%#o, mode=%#o)", path.get_ptr(), flags, mode); return CELL_FS_ENOENT; } + + std::shared_ptr file_handler(new fs_file_t(file, mode, flags)); - *fd = Emu.GetIdManager().GetNewID(file, TYPE_FS_FILE); + *fd = Emu.GetIdManager().GetNewID(file_handler, TYPE_FS_FILE); return CELL_OK; } @@ -126,14 +128,14 @@ s32 sys_fs_read(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nread) { sys_fs.Log("sys_fs_read(fd=0x%x, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread); - std::shared_ptr file; + std::shared_ptr file; - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!Emu.GetIdManager().GetIDData(fd, file) || file->flags & CELL_FS_O_WRONLY) { - return CELL_FS_EBADF; // TODO: return if not opened for reading + return CELL_FS_EBADF; } - *nread = file->Read(buf.get_ptr(), nbytes); + *nread = file->file->Read(buf.get_ptr(), nbytes); return CELL_OK; } @@ -142,16 +144,16 @@ s32 sys_fs_write(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrit { sys_fs.Log("sys_fs_write(fd=0x%x, buf=*0x%x, nbytes=0x%llx, nwrite=*0x%x)", fd, buf, nbytes, nwrite); - std::shared_ptr file; + std::shared_ptr file; - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!Emu.GetIdManager().GetIDData(fd, file) || !(file->flags & CELL_FS_O_ACCMODE)) { - return CELL_FS_EBADF; // TODO: return if not opened for writing + return CELL_FS_EBADF; } // TODO: return CELL_FS_EBUSY if locked - *nwrite = file->Write(buf.get_ptr(), nbytes); + *nwrite = file->file->Write(buf.get_ptr(), nbytes); return CELL_OK; } @@ -160,7 +162,7 @@ s32 sys_fs_close(u32 fd) { sys_fs.Log("sys_fs_close(fd=0x%x)", fd); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) { @@ -169,7 +171,7 @@ s32 sys_fs_close(u32 fd) // TODO: return CELL_FS_EBUSY if locked - Emu.GetIdManager().RemoveID(fd); + Emu.GetIdManager().RemoveID(fd); return CELL_OK; } @@ -323,7 +325,7 @@ s32 sys_fs_fstat(u32 fd, vm::ptr sb) { sys_fs.Warning("sys_fs_fstat(fd=0x%x, sb=*0x%x)", fd, sb); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -338,7 +340,7 @@ s32 sys_fs_fstat(u32 fd, vm::ptr sb) sb->atime = 0; //TODO sb->mtime = 0; //TODO sb->ctime = 0; //TODO - sb->size = file->GetSize(); + sb->size = file->file->GetSize(); sb->blksize = 4096; return CELL_OK; @@ -451,11 +453,11 @@ s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr pos) return CELL_EINVAL; } - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; - *pos = file->Seek(offset, seek_mode); + *pos = file->file->Seek(offset, seek_mode); return CELL_OK; } @@ -463,7 +465,7 @@ s32 sys_fs_fget_block_size(u32 fd, vm::ptr sector_size, vm::ptr block_ { sys_fs.Todo("sys_fs_fget_block_size(fd=%d, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", fd, sector_size, block_size, arg4, arg5); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; @@ -519,20 +521,20 @@ s32 sys_fs_ftruncate(u32 fd, u64 size) { sys_fs.Warning("sys_fs_ftruncate(fd=0x%x, size=0x%llx)", fd, size); - std::shared_ptr file; + std::shared_ptr file; if (!Emu.GetIdManager().GetIDData(fd, file)) return CELL_ESRCH; - u64 initialSize = file->GetSize(); + u64 initialSize = file->file->GetSize(); if (initialSize < size) { - u64 last_pos = file->Tell(); - file->Seek(0, vfsSeekEnd); + u64 last_pos = file->file->Tell(); + file->file->Seek(0, vfsSeekEnd); static const char nullbyte = 0; - file->Seek(size - initialSize - 1, vfsSeekCur); - file->Write(&nullbyte, sizeof(char)); - file->Seek(last_pos, vfsSeekSet); + file->file->Seek(size - initialSize - 1, vfsSeekCur); + file->file->Write(&nullbyte, sizeof(char)); + file->file->Seek(last_pos, vfsSeekSet); } if (initialSize > size) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.h b/rpcs3/Emu/SysCalls/lv2/sys_fs.h index 7515e7f7b5..08f5d86773 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.h @@ -144,6 +144,20 @@ struct CellFsUtimbuf #pragma pack(pop) +struct fs_file_t +{ + const std::shared_ptr file; + const s32 mode; + const s32 flags; + + fs_file_t(std::shared_ptr& file, s32 mode, s32 flags) + : file(file) + , mode(mode) + , flags(flags) + { + } +}; + // SysCalls s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, vm::ptr arg, u64 size); s32 sys_fs_read(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nread);