From f1f55cea475b2e75c188d657bfb846f8ddf7fc5b Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Wed, 16 Jul 2014 02:08:54 -0700 Subject: [PATCH] Use VFiles for all file operations --- src/gba/gba-savedata.c | 89 +++++++++++++++++++++-------------- src/gba/gba-savedata.h | 4 +- src/gba/gba-serialize.c | 39 ++++++++------- src/gba/gba-serialize.h | 6 ++- src/gba/gba-thread.c | 12 ++--- src/gba/gba-thread.h | 6 +-- src/gba/gba.c | 31 ++++++++---- src/gba/gba.h | 9 ++-- src/platform/posix/memory.c | 7 --- src/platform/windows/memory.c | 17 ------- src/util/memory.h | 1 - src/util/vfile.c | 65 ++++++++++++++++++++++++- src/util/vfile.h | 5 ++ 13 files changed, 189 insertions(+), 102 deletions(-) diff --git a/src/gba/gba-savedata.c b/src/gba/gba-savedata.c index 39cef502c..d56689549 100644 --- a/src/gba/gba-savedata.c +++ b/src/gba/gba-savedata.c @@ -3,6 +3,7 @@ #include "gba.h" #include "util/memory.h" +#include "util/vfile.h" #include #include @@ -16,7 +17,7 @@ void GBASavedataInit(struct GBASavedata* savedata, const char* filename) { savedata->data = 0; savedata->command = EEPROM_COMMAND_NULL; savedata->flashState = FLASH_STATE_RAW; - savedata->fd = -1; + savedata->vf = 0; savedata->filename = filename; } @@ -29,24 +30,42 @@ void GBASavedataForceType(struct GBASavedata* savedata, enum SavedataType type) } void GBASavedataDeinit(struct GBASavedata* savedata) { - switch (savedata->type) { - case SAVEDATA_SRAM: - mappedMemoryFree(savedata->data, SIZE_CART_SRAM); - break; - case SAVEDATA_FLASH512: - mappedMemoryFree(savedata->data, SIZE_CART_FLASH512); - break; - case SAVEDATA_FLASH1M: - mappedMemoryFree(savedata->data, SIZE_CART_FLASH1M); - break; - case SAVEDATA_EEPROM: - mappedMemoryFree(savedata->data, SIZE_CART_EEPROM); - break; - default: - break; - } - if (savedata->fd >= 0) { - close(savedata->fd); + if (savedata->vf) { + switch (savedata->type) { + case SAVEDATA_SRAM: + savedata->vf->unmap(savedata->vf, savedata->data, SIZE_CART_SRAM); + break; + case SAVEDATA_FLASH512: + savedata->vf->unmap(savedata->vf, savedata->data, SIZE_CART_FLASH512); + break; + case SAVEDATA_FLASH1M: + savedata->vf->unmap(savedata->vf, savedata->data, SIZE_CART_FLASH1M); + break; + case SAVEDATA_EEPROM: + savedata->vf->unmap(savedata->vf, savedata->data, SIZE_CART_EEPROM); + break; + case SAVEDATA_NONE: + break; + } + savedata->vf->close(savedata->vf); + savedata->vf = 0; + } else { + switch (savedata->type) { + case SAVEDATA_SRAM: + mappedMemoryFree(savedata->data, SIZE_CART_SRAM); + break; + case SAVEDATA_FLASH512: + mappedMemoryFree(savedata->data, SIZE_CART_FLASH512); + break; + case SAVEDATA_FLASH1M: + mappedMemoryFree(savedata->data, SIZE_CART_FLASH1M); + break; + case SAVEDATA_EEPROM: + mappedMemoryFree(savedata->data, SIZE_CART_EEPROM); + break; + case SAVEDATA_NONE: + break; + } } savedata->type = SAVEDATA_NONE; } @@ -59,18 +78,18 @@ void GBASavedataInitFlash(struct GBASavedata* savedata) { GBALog(0, GBA_LOG_WARN, "Can't re-initialize savedata"); return; } - savedata->fd = open(savedata->filename, O_RDWR | O_CREAT, 0666); + savedata->vf = VFileOpen(savedata->filename, O_RDWR | O_CREAT); off_t end; - if (savedata->fd < 0) { + if (!savedata->vf) { GBALog(0, GBA_LOG_ERROR, "Cannot open savedata file %s (errno: %d)", savedata->filename, errno); end = 0; savedata->data = anonymousMemoryMap(SIZE_CART_FLASH1M); } else { - end = lseek(savedata->fd, 0, SEEK_END); + end = savedata->vf->seek(savedata->vf, 0, SEEK_END); if (end < SIZE_CART_FLASH512) { - ftruncate(savedata->fd, SIZE_CART_FLASH1M); + savedata->vf->truncate(savedata->vf, SIZE_CART_FLASH1M); } - savedata->data = fileMemoryMap(savedata->fd, SIZE_CART_FLASH1M, MEMORY_WRITE); + savedata->data = savedata->vf->map(savedata->vf, SIZE_CART_FLASH1M, MEMORY_WRITE); } savedata->currentBank = savedata->data; @@ -86,18 +105,18 @@ void GBASavedataInitEEPROM(struct GBASavedata* savedata) { GBALog(0, GBA_LOG_WARN, "Can't re-initialize savedata"); return; } - savedata->fd = open(savedata->filename, O_RDWR | O_CREAT, 0666); + savedata->vf = VFileOpen(savedata->filename, O_RDWR | O_CREAT); off_t end; - if (savedata->fd < 0) { + if (!savedata->vf) { GBALog(0, GBA_LOG_ERROR, "Cannot open savedata file %s (errno: %d)", savedata->filename, errno); end = 0; savedata->data = anonymousMemoryMap(SIZE_CART_EEPROM); } else { - end = lseek(savedata->fd, 0, SEEK_END); + end = savedata->vf->seek(savedata->vf, 0, SEEK_END); if (end < SIZE_CART_EEPROM) { - ftruncate(savedata->fd, SIZE_CART_EEPROM); + savedata->vf->truncate(savedata->vf, SIZE_CART_EEPROM); } - savedata->data = fileMemoryMap(savedata->fd, SIZE_CART_EEPROM, MEMORY_WRITE); + savedata->data = savedata->vf->map(savedata->vf, SIZE_CART_EEPROM, MEMORY_WRITE); } if (end < SIZE_CART_EEPROM) { memset(&savedata->data[end], 0xFF, SIZE_CART_EEPROM - end); @@ -111,18 +130,18 @@ void GBASavedataInitSRAM(struct GBASavedata* savedata) { GBALog(0, GBA_LOG_WARN, "Can't re-initialize savedata"); return; } - savedata->fd = open(savedata->filename, O_RDWR | O_CREAT, 0666); + savedata->vf = VFileOpen(savedata->filename, O_RDWR | O_CREAT); off_t end; - if (savedata->fd < 0) { + if (!savedata->vf) { GBALog(0, GBA_LOG_ERROR, "Cannot open savedata file %s (errno: %d)", savedata->filename, errno); end = 0; savedata->data = anonymousMemoryMap(SIZE_CART_SRAM); } else { - end = lseek(savedata->fd, 0, SEEK_END); + end = savedata->vf->seek(savedata->vf, 0, SEEK_END); if (end < SIZE_CART_SRAM) { - ftruncate(savedata->fd, SIZE_CART_SRAM); + savedata->vf->truncate(savedata->vf, SIZE_CART_SRAM); } - savedata->data = fileMemoryMap(savedata->fd, SIZE_CART_SRAM, MEMORY_WRITE); + savedata->data = savedata->vf->map(savedata->vf, SIZE_CART_SRAM, MEMORY_WRITE); } if (end < SIZE_CART_SRAM) { @@ -299,7 +318,7 @@ void _flashSwitchBank(struct GBASavedata* savedata, int bank) { savedata->currentBank = &savedata->data[bank << 16]; if (bank > 0) { savedata->type = SAVEDATA_FLASH1M; - ftruncate(savedata->fd, SIZE_CART_FLASH1M); + savedata->vf->truncate(savedata->vf, SIZE_CART_FLASH1M); } } diff --git a/src/gba/gba-savedata.h b/src/gba/gba-savedata.h index 707680fd2..15a3cca57 100644 --- a/src/gba/gba-savedata.h +++ b/src/gba/gba-savedata.h @@ -3,6 +3,8 @@ #include "common.h" +struct VFile; + enum SavedataType { SAVEDATA_NONE = 0, SAVEDATA_SRAM, @@ -55,7 +57,7 @@ struct GBASavedata { uint8_t* data; const char* filename; enum SavedataCommand command; - int fd; + struct VFile* vf; int readBitsRemaining; int readAddress; diff --git a/src/gba/gba-serialize.c b/src/gba/gba-serialize.c index 374dc7a4b..11d28551a 100644 --- a/src/gba/gba-serialize.c +++ b/src/gba/gba-serialize.c @@ -5,6 +5,7 @@ #include "gba-thread.h" #include "util/memory.h" +#include "util/vfile.h" #include @@ -62,43 +63,47 @@ void GBADeserialize(struct GBA* gba, struct GBASerializedState* state) { GBAAudioDeserialize(&gba->audio, state); } -static int _getStateFd(struct GBA* gba, int slot) { +static struct VFile* _getStateVf(struct GBA* gba, int slot) { char path[PATH_MAX]; path[PATH_MAX - 1] = '\0'; snprintf(path, PATH_MAX - 1, "%s.ss%d", gba->activeFile, slot); - int fd = open(path, O_CREAT | O_RDWR, 0777); - if (fd >= 0) { - ftruncate(fd, sizeof(struct GBASerializedState)); + struct VFile* vf = VFileOpen(path, O_CREAT | O_RDWR); + if (vf) { + vf->truncate(vf, sizeof(struct GBASerializedState)); } - return fd; + return vf; } bool GBASaveState(struct GBA* gba, int slot) { - int fd = _getStateFd(gba, slot); - if (fd < 0) { + struct VFile* vf = _getStateVf(gba, slot); + if (!vf) { return false; } - struct GBASerializedState* state = GBAMapState(fd); + struct GBASerializedState* state = GBAMapState(vf); GBASerialize(gba, state); - GBADeallocateState(state); - close(fd); + GBAUnmapState(vf, state); + vf->close(vf); return true; } bool GBALoadState(struct GBA* gba, int slot) { - int fd = _getStateFd(gba, slot); - if (fd < 0) { + struct VFile* vf = _getStateVf(gba, slot); + if (!vf) { return false; } - struct GBASerializedState* state = GBAMapState(fd); + struct GBASerializedState* state = GBAMapState(vf); GBADeserialize(gba, state); - GBADeallocateState(state); - close(fd); + GBAUnmapState(vf, state); + vf->close(vf); return true; } -struct GBASerializedState* GBAMapState(int fd) { - return fileMemoryMap(fd, sizeof(struct GBASerializedState), MEMORY_WRITE); +struct GBASerializedState* GBAMapState(struct VFile* vf) { + return vf->map(vf, sizeof(struct GBASerializedState), MEMORY_WRITE); +} + +void GBAUnmapState(struct VFile* vf, struct GBASerializedState* state) { + vf->unmap(vf, state, sizeof(struct GBASerializedState)); } struct GBASerializedState* GBAAllocateState(void) { diff --git a/src/gba/gba-serialize.h b/src/gba/gba-serialize.h index d4e52b498..cefc50e62 100644 --- a/src/gba/gba-serialize.h +++ b/src/gba/gba-serialize.h @@ -225,13 +225,17 @@ struct GBASerializedState { uint8_t wram[SIZE_WORKING_RAM]; }; +struct VFile; + void GBASerialize(struct GBA* gba, struct GBASerializedState* state); void GBADeserialize(struct GBA* gba, struct GBASerializedState* state); bool GBASaveState(struct GBA* gba, int slot); bool GBALoadState(struct GBA* gba, int slot); -struct GBASerializedState* GBAMapState(int fd); +struct GBASerializedState* GBAMapState(struct VFile* vf); +void GBAUnmapState(struct VFile* vf, struct GBASerializedState* state); + struct GBASerializedState* GBAAllocateState(void); void GBADeallocateState(struct GBASerializedState* state); diff --git a/src/gba/gba-thread.c b/src/gba/gba-thread.c index f1f75f49c..c7de7d61d 100644 --- a/src/gba/gba-thread.c +++ b/src/gba/gba-thread.c @@ -89,7 +89,7 @@ static THREAD_ENTRY _GBAThreadRun(void* context) { GBAVideoAssociateRenderer(&gba.video, threadContext->renderer); } - if (threadContext->fd >= 0) { + if (threadContext->fd) { if (threadContext->fname) { char* dotPoint = strrchr(threadContext->fname, '.'); if (dotPoint > strrchr(threadContext->fname, '/') && dotPoint[1] && dotPoint[2] && dotPoint[3]) { @@ -111,11 +111,11 @@ static THREAD_ENTRY _GBAThreadRun(void* context) { } gba.savefile = savedata; GBALoadROM(&gba, threadContext->fd, threadContext->fname); - if (threadContext->biosFd >= 0) { + if (threadContext->biosFd) { GBALoadBIOS(&gba, threadContext->biosFd); } - if (threadContext->patchFd >= 0 && loadPatch(VFileFromFD(threadContext->patchFd), &patch)) { + if (threadContext->patchFd && loadPatch(threadContext->patchFd, &patch)) { GBAApplyPatch(&gba, &patch); } } @@ -191,10 +191,10 @@ static THREAD_ENTRY _GBAThreadRun(void* context) { } void GBAMapOptionsToContext(struct StartupOptions* opts, struct GBAThread* threadContext) { - threadContext->fd = opts->fd; + threadContext->fd = VFileFromFD(opts->fd); threadContext->fname = opts->fname; - threadContext->biosFd = opts->biosFd; - threadContext->patchFd = opts->patchFd; + threadContext->biosFd = VFileFromFD(opts->biosFd); + threadContext->patchFd = VFileFromFD(opts->patchFd); threadContext->frameskip = opts->frameskip; threadContext->logLevel = opts->logLevel; threadContext->rewindBufferCapacity = opts->rewindBufferCapacity; diff --git a/src/gba/gba-thread.h b/src/gba/gba-thread.h index 1f80eabc5..4db039da3 100644 --- a/src/gba/gba-thread.h +++ b/src/gba/gba-thread.h @@ -47,9 +47,9 @@ struct GBAThread { struct GBAVideoRenderer* renderer; struct GBASIODriverSet sioDrivers; struct ARMDebugger* debugger; - int fd; - int biosFd; - int patchFd; + struct VFile* fd; + struct VFile* biosFd; + struct VFile* patchFd; const char* fname; int activeKeys; int frameskip; diff --git a/src/gba/gba.c b/src/gba/gba.c index b5fd146ef..1018a6e6d 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -7,8 +7,7 @@ #include "util/memory.h" #include "util/patch.h" - -#include +#include "util/vfile.h" const uint32_t GBA_ARM7TDMI_FREQUENCY = 0x1000000; const uint32_t GBA_COMPONENT_MAGIC = 0x1000000; @@ -134,6 +133,9 @@ static void GBAInit(struct ARMCore* cpu, struct ARMComponent* component) { gba->rotationSource = 0; gba->rumble = 0; + gba->romVf = 0; + gba->biosVf = 0; + gba->logLevel = GBA_LOG_INFO | GBA_LOG_WARN | GBA_LOG_ERROR | GBA_LOG_FATAL; gba->biosChecksum = GBAChecksum(gba->memory.bios, SIZE_BIOS); @@ -143,7 +145,15 @@ void GBADestroy(struct GBA* gba) { if (gba->pristineRom == gba->memory.rom) { gba->memory.rom = 0; } - mappedMemoryFree(gba->pristineRom, gba->pristineRomSize); + + if (gba->romVf) { + gba->romVf->unmap(gba->romVf, gba->pristineRom, gba->pristineRomSize); + } + + if (gba->biosVf) { + gba->biosVf->unmap(gba->biosVf, gba->memory.bios, SIZE_BIOS); + } + GBAMemoryDeinit(gba); GBAVideoDeinit(&gba->video); GBAAudioDeinit(&gba->audio); @@ -363,13 +373,13 @@ void GBADetachDebugger(struct GBA* gba) { gba->debugger = 0; } -void GBALoadROM(struct GBA* gba, int fd, const char* fname) { - struct stat info; - gba->pristineRom = fileMemoryMap(fd, SIZE_CART0, MEMORY_READ); +void GBALoadROM(struct GBA* gba, struct VFile* vf, const char* fname) { + gba->romVf = vf; + gba->pristineRomSize = vf->seek(vf, 0, SEEK_END); + vf->seek(vf, 0, SEEK_SET); + gba->pristineRom = vf->map(vf, SIZE_CART0, MEMORY_READ); gba->memory.rom = gba->pristineRom; gba->activeFile = fname; - fstat(fd, &info); - gba->pristineRomSize = info.st_size; gba->memory.romSize = gba->pristineRomSize; if (gba->savefile) { GBASavedataInit(&gba->memory.savedata, gba->savefile); @@ -379,8 +389,9 @@ void GBALoadROM(struct GBA* gba, int fd, const char* fname) { // TODO: error check } -void GBALoadBIOS(struct GBA* gba, int fd) { - gba->memory.bios = fileMemoryMap(fd, SIZE_BIOS, MEMORY_READ); +void GBALoadBIOS(struct GBA* gba, struct VFile* vf) { + gba->biosVf = vf; + gba->memory.bios = vf->map(vf, SIZE_BIOS, MEMORY_READ); gba->memory.fullBios = 1; uint32_t checksum = GBAChecksum(gba->memory.bios, SIZE_BIOS); GBALog(gba, GBA_LOG_DEBUG, "BIOS Checksum: 0x%X", checksum); diff --git a/src/gba/gba.h b/src/gba/gba.h index 9b5bd0d38..d49694958 100644 --- a/src/gba/gba.h +++ b/src/gba/gba.h @@ -60,9 +60,10 @@ enum GBAKey { GBA_KEY_NONE = -1 }; -struct GBARotationSource; struct GBA; +struct GBARotationSource; struct Patch; +struct VFile; typedef void (*GBALogHandler)(struct GBA*, enum GBALogLevel, const char* format, va_list args); @@ -99,6 +100,8 @@ struct GBA { struct GBARumble* rumble; void* pristineRom; size_t pristineRomSize; + struct VFile* romVf; + struct VFile* biosVf; const char* activeFile; const char* savefile; @@ -141,8 +144,8 @@ void GBAHalt(struct GBA* gba); void GBAAttachDebugger(struct GBA* gba, struct ARMDebugger* debugger); void GBADetachDebugger(struct GBA* gba); -void GBALoadROM(struct GBA* gba, int fd, const char* fname); -void GBALoadBIOS(struct GBA* gba, int fd); +void GBALoadROM(struct GBA* gba, struct VFile* vf, const char* fname); +void GBALoadBIOS(struct GBA* gba, struct VFile* vf); void GBAApplyPatch(struct GBA* gba, struct Patch* patch); __attribute__((format (printf, 3, 4))) diff --git a/src/platform/posix/memory.c b/src/platform/posix/memory.c index d4d69d993..4b9af967a 100644 --- a/src/platform/posix/memory.c +++ b/src/platform/posix/memory.c @@ -5,13 +5,6 @@ void* anonymousMemoryMap(size_t size) { return mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); } -void* fileMemoryMap(int fd, size_t size, int flags) { - int mmapFlags = MAP_PRIVATE; - if (flags & MEMORY_WRITE) { - mmapFlags = MAP_SHARED; - } - return mmap(0, size, PROT_READ | PROT_WRITE, mmapFlags, fd, 0); -} void mappedMemoryFree(void* memory, size_t size) { munmap(memory, size); diff --git a/src/platform/windows/memory.c b/src/platform/windows/memory.c index cd9748a45..dfc43311e 100644 --- a/src/platform/windows/memory.c +++ b/src/platform/windows/memory.c @@ -8,23 +8,6 @@ void* anonymousMemoryMap(size_t size) { return MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, size); } -void* fileMemoryMap(int fd, size_t size, int flags) { - int createFlags = PAGE_READONLY; - int mapFiles = FILE_MAP_READ; - if (flags & MEMORY_WRITE) { - createFlags = PAGE_READWRITE; - mapFiles = FILE_MAP_WRITE; - } - size_t location = lseek(fd, 0, SEEK_CUR); - size_t fileSize = lseek(fd, 0, SEEK_END); - lseek(fd, location, SEEK_SET); - if (size > fileSize) { - size = fileSize; - } - HANDLE hMap = CreateFileMapping((HANDLE) _get_osfhandle(fd), 0, createFlags, 0, size & 0xFFFFFFFF, 0); - return MapViewOfFile(hMap, mapFiles, 0, 0, size); -} - void mappedMemoryFree(void* memory, size_t size) { // TODO fill in } diff --git a/src/util/memory.h b/src/util/memory.h index c9c04fbfb..e9539ef1f 100644 --- a/src/util/memory.h +++ b/src/util/memory.h @@ -7,7 +7,6 @@ #define MEMORY_WRITE 2 void* anonymousMemoryMap(size_t size); -void* fileMemoryMap(int fd, size_t size, int flags); void mappedMemoryFree(void* memory, size_t size); #endif diff --git a/src/util/vfile.c b/src/util/vfile.c index 7e453866b..60b2356b8 100644 --- a/src/util/vfile.c +++ b/src/util/vfile.c @@ -2,9 +2,19 @@ #include +#ifndef _WIN32 +#include +#else +#include +#include +#endif + struct VFileFD { struct VFile d; int fd; +#ifdef _WIN32 + HANDLE hMap; +#endif }; static bool _vfdClose(struct VFile* vf); @@ -12,9 +22,12 @@ static size_t _vfdSeek(struct VFile* vf, off_t offset, int whence); static size_t _vfdRead(struct VFile* vf, void* buffer, size_t size); static size_t _vfdReadline(struct VFile* vf, char* buffer, size_t size); static size_t _vfdWrite(struct VFile* vf, void* buffer, size_t size); +static void* _vfdMap(struct VFile* vf, size_t size, int flags); +static void _vfdUnmap(struct VFile* vf, void* memory, size_t size); +static void _vfdTruncate(struct VFile* vf, size_t size); struct VFile* VFileOpen(const char* path, int flags) { - int fd = open(path, flags); + int fd = open(path, flags, 0666); return VFileFromFD(fd); } @@ -34,6 +47,9 @@ struct VFile* VFileFromFD(int fd) { vfd->d.read = _vfdRead; vfd->d.readline = _vfdReadline; vfd->d.write = _vfdWrite; + vfd->d.map = _vfdMap; + vfd->d.unmap = _vfdUnmap; + vfd->d.truncate = _vfdTruncate; return &vfd->d; } @@ -74,3 +90,50 @@ size_t _vfdWrite(struct VFile* vf, void* buffer, size_t size) { struct VFileFD* vfd = (struct VFileFD*) vf; return write(vfd->fd, buffer, size); } + +#ifndef _WIN32 +static void* _vfdMap(struct VFile* vf, size_t size, int flags) { + struct VFileFD* vfd = (struct VFileFD*) vf; + int mmapFlags = MAP_PRIVATE; + if (flags & MEMORY_WRITE) { + mmapFlags = MAP_SHARED; + } + return mmap(0, size, PROT_READ | PROT_WRITE, mmapFlags, vfd->fd, 0); +} + +static void _vfdUnmap(struct VFile* vf, void* memory, size_t size) { + UNUSED(vf); + munmap(memory, size); +} +#else +static void* _vfdMap(struct VFile* vf, size_t size, int flags) { + struct VFileFD* vfd = (struct VFileFD*) vf; + int createFlags = PAGE_READONLY; + int mapFiles = FILE_MAP_READ; + if (flags & MEMORY_WRITE) { + createFlags = PAGE_READWRITE; + mapFiles = FILE_MAP_WRITE; + } + size_t location = lseek(vfd->fd, 0, SEEK_CUR); + size_t fileSize = lseek(vfd->fd, 0, SEEK_END); + lseek(vfd->fd, location, SEEK_SET); + if (size > fileSize) { + size = fileSize; + } + vfd->hMap = CreateFileMapping((HANDLE) _get_osfhandle(vfd->fd), 0, createFlags, 0, size & 0xFFFFFFFF, 0); + return MapViewOfFile(hMap, mapFiles, 0, 0, size); +} + +static void _vfdUnmap(struct VFile* vf, void* memory, size_t size) { + UNUSED(size); + struct VFileFD* vfd = (struct VFileFD*) vf; + UnmapViewOfFile(memory); + CloseHandle(vfd->hMap); + vfd->hMap = 0; +} +#endif + +static void _vfdTruncate(struct VFile* vf, size_t size) { + struct VFileFD* vfd = (struct VFileFD*) vf; + ftruncate(vfd->fd, size); +} diff --git a/src/util/vfile.h b/src/util/vfile.h index b597d6cf4..c80aa9483 100644 --- a/src/util/vfile.h +++ b/src/util/vfile.h @@ -3,12 +3,17 @@ #include "common.h" +#include "memory.h" + struct VFile { bool (*close)(struct VFile* vf); size_t (*seek)(struct VFile* vf, off_t offset, int whence); size_t (*read)(struct VFile* vf, void* buffer, size_t size); size_t (*readline)(struct VFile* vf, char* buffer, size_t size); size_t (*write)(struct VFile* vf, void* buffer, size_t size); + void* (*map)(struct VFile* vf, size_t size, int flags); + void (*unmap)(struct VFile* vf, void* memory, size_t size); + void (*truncate)(struct VFile* vf, size_t size); }; struct VFile* VFileOpen(const char* path, int flags);