#include "imcs.h" #include "fileio.h" #ifdef _WIN32 imcs_file_h imcs_file_open(char const* path) { HANDLE h = CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL); if (h == INVALID_HANDLE_VALUE) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FILE), errmsg("Failed to open file '%s': %d", path, GetLastError()))); } return h; } bool imcs_file_read(imcs_file_h file, void* buf, size_t size, off_t pos) { DWORD readBytes = 0; OVERLAPPED Overlapped; Overlapped.Offset = (DWORD)LO_32(pos); Overlapped.OffsetHigh = (DWORD)HI_32(pos); Overlapped.hEvent = NULL; if (ReadFile(file, buf, size, &readBytes, &Overlapped)) { if (readBytes != size) { ereport(ERROR, (errcode(ERRCODE_IO_ERROR), errmsg("Read %d bytes from file instead of %ld", readBytes, size))); } } else { int rc = GetLastError(); if (rc != ERROR_HANDLE_EOF) { ereport(ERROR, (errcode(ERRCODE_IO_ERROR), errmsg("File read failed: %d", GetLastError()))); } } return readBytes != 0; } void imcs_file_write(imcs_file_h file, void const* buf, size_t size, off_t pos) { DWORD writtenBytes; OVERLAPPED Overlapped; Overlapped.Offset = (DWORD)LO_32(pos); Overlapped.OffsetHigh = (DWORD)HI_32(pos); Overlapped.hEvent = NULL; if (!WriteFile(file, buf, size, &writtenBytes, &Overlapped)) { ereport(ERROR, (errcode(ERRCODE_IO_ERROR), errmsg("File write failed: %d", GetLastError()))); } else if (writtenBytes != size) { ereport(ERROR, (errcode(ERRCODE_IO_ERROR), errmsg("Write %d bytes from file instead of %ld", writtenBytes, size))); } } void imcs_file_close(imcs_file_h file) { if (!CloseHandle(file)) { ereport(ERROR, (errcode(ERRCODE_IO_ERROR), errmsg("File close failed: %d", GetLastError()))); } } #else #include #include #include #include #include #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif imcs_file_h imcs_file_open(char const* path) { int rc = open(path, O_LARGEFILE | O_RDWR | O_CREAT, 0600); if (rc < 0) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FILE), errmsg("Failed to open file '%s': %d", path, errno))); } return rc; } bool imcs_file_read(imcs_file_h file, void* buf, size_t size, off_t pos) { ssize_t rc = pread(file, buf, size, pos); if (rc != 0 && rc != size) { ereport(ERROR, (errcode(ERRCODE_IO_ERROR), errmsg("File read failed: %d", errno))); } return rc != 0; } void imcs_file_write(imcs_file_h file, void const* buf, size_t size, off_t pos) { ssize_t rc = pwrite(file, buf, size, pos); if (rc != size) { ereport(ERROR, (errcode(ERRCODE_IO_ERROR), errmsg("File write failed: %d", errno))); } } void imcs_file_close(imcs_file_h file) { if (close(file) < 0) { ereport(ERROR, (errcode(ERRCODE_IO_ERROR), errmsg("File close failed: %d", errno))); } } #endif