diff options
Diffstat (limited to '')
-rw-r--r-- | storage/connect/maputil.cpp | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/storage/connect/maputil.cpp b/storage/connect/maputil.cpp new file mode 100644 index 00000000..903798bc --- /dev/null +++ b/storage/connect/maputil.cpp @@ -0,0 +1,200 @@ +#include "my_global.h" +#ifdef UNIX +#include "osutil.h" +#include <errno.h> +#include <stddef.h> +#else /* WINDOWS */ +//#include <windows.h> +#include "osutil.h" +#endif /* WINDOWS */ +#include <stdlib.h> +#include <stdio.h> + +#include "global.h" +#include "plgdbsem.h" +#include "maputil.h" + +#ifdef _WIN32 +/***********************************************************************/ +/* In Insert mode, just open the file for append. Otherwise */ +/* create the mapping file object. The map handle can be released */ +/* immediately because they will not be used anymore. */ +/* If del is true in DELETE mode, then delete the whole file. */ +/* Returns the file handle that can be used by caller. */ +/***********************************************************************/ +HANDLE CreateFileMap(PGLOBAL g, LPCSTR filename, + MEMMAP *mm, MODE mode, bool del) + { + HANDLE hFile; + HANDLE hFileMap; + DWORD access, share, disposition; + + memset(mm, 0, sizeof(MEMMAP)); + *g->Message = '\0'; + + switch (mode) { + case MODE_READ: + access = GENERIC_READ; + share = FILE_SHARE_READ; + disposition = OPEN_EXISTING; + break; + case MODE_UPDATE: + case MODE_DELETE: + access = GENERIC_READ | GENERIC_WRITE; + share = 0; + disposition = (del) ? TRUNCATE_EXISTING : OPEN_EXISTING; + break; + case MODE_INSERT: + access = GENERIC_WRITE; + share = 0; + disposition = OPEN_ALWAYS; + break; + default: + snprintf(g->Message, sizeof(g->Message), MSG(BAD_FUNC_MODE), "CreateFileMap", mode); + return INVALID_HANDLE_VALUE; + } // endswitch + + hFile = CreateFile(filename, access, share, NULL, disposition, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile != INVALID_HANDLE_VALUE) + if (mode != MODE_INSERT) { + /*****************************************************************/ + /* Create the file-mapping object. */ + /*****************************************************************/ + access = (mode == MODE_READ) ? PAGE_READONLY : PAGE_READWRITE; + hFileMap = CreateFileMapping(hFile, NULL, access, 0, 0, NULL); + + if (!hFileMap) { + DWORD ler = GetLastError(); + + if (ler && ler != 1006) { + snprintf(g->Message, sizeof(g->Message), MSG(FILE_MAP_ERROR), filename, ler); + CloseHandle(hFile); + return INVALID_HANDLE_VALUE; + } else { + snprintf(g->Message, sizeof(g->Message), MSG(FILE_IS_EMPTY), filename); + return hFile; + } // endif ler + + } // endif hFileMap + + access = (mode == MODE_READ) ? FILE_MAP_READ : FILE_MAP_WRITE; + + if (!(mm->memory = MapViewOfFile(hFileMap, access, 0, 0, 0))) { + DWORD ler = GetLastError(); + + snprintf(g->Message, sizeof(g->Message), "Error %ld in MapViewOfFile %s", + ler, filename); + CloseHandle(hFile); + return INVALID_HANDLE_VALUE; + } // endif memory + + // lenH is the high-order word of the file size + mm->lenL = GetFileSize(hFile, &mm->lenH); + CloseHandle(hFileMap); // Not used anymore + } else // MODE_INSERT + /*****************************************************************/ + /* The starting point must be the end of file as for append. */ + /*****************************************************************/ + SetFilePointer(hFile, 0, NULL, FILE_END); + + return hFile; + } // end of CreateFileMap + +bool CloseMemMap(LPVOID memory, size_t dwSize) + { + return (memory) ? !UnmapViewOfFile(memory) : false; + } // end of CloseMemMap + +#else /* UNIX */ +// Code to handle Linux and Solaris +#include <sys/types.h> +#include <sys/mman.h> +#include <unistd.h> +#include <sys/stat.h> +#include <fcntl.h> + +/***********************************************************************/ +/* In Insert mode, just open the file for append. Otherwise */ +/* create the mapping file object. The map handle can be released */ +/* immediately because they will not be used anymore. */ +/* If del is true in DELETE mode, then delete the whole file. */ +/* Returns the file handle that can be used by caller. */ +/***********************************************************************/ +HANDLE CreateFileMap(PGLOBAL g, LPCSTR fileName, + MEMMAP *mm, MODE mode, bool del) + { + unsigned int openMode; + int protmode; + HANDLE fd; + size_t filesize; + struct stat st; + + memset(mm, 0, sizeof(MEMMAP)); + *g->Message = '\0'; + + switch (mode) { + case MODE_READ: + openMode = O_RDONLY; + protmode = PROT_READ; + break; + case MODE_UPDATE: + case MODE_DELETE: + openMode = (del) ? (O_RDWR | O_TRUNC) : O_RDWR; + protmode = PROT_READ | PROT_WRITE; + break; + case MODE_INSERT: + openMode = (O_WRONLY | O_CREAT | O_APPEND); + protmode = PROT_WRITE; + break; + default: + snprintf(g->Message, sizeof(g->Message), MSG(BAD_FUNC_MODE), "CreateFileMap", mode); + return INVALID_HANDLE_VALUE; + } // endswitch + + // Try to open the addressed file. + fd= global_open(g, MSGID_NONE, fileName, openMode); + + if (fd != INVALID_HANDLE_VALUE && mode != MODE_INSERT) { + /* We must know about the size of the file. */ + if (fstat(fd, &st)) { + snprintf(g->Message, sizeof(g->Message), MSG(FILE_MAP_ERROR), fileName, errno); + close(fd); + return INVALID_HANDLE_VALUE; + } // endif fstat + + if ((filesize = st.st_size)) + // Now we are ready to load the file. If mmap() is available we try + // this first. If not available or it failed we try to load it. + mm->memory = mmap(NULL, filesize, protmode, MAP_SHARED, fd, 0); + else + mm->memory = 0; + + if (mm->memory != MAP_FAILED) { + mm->lenL = (mm->memory != 0) ? filesize : 0; + mm->lenH = 0; + } else { + strcpy(g->Message, "Memory mapping failed"); + close(fd); + return INVALID_HANDLE_VALUE; + } // endif memory + + } /* endif fd */ + + // mmap() call was successful. ?????????? + return fd; + } // end of CreateFileMap + +bool CloseMemMap(void *memory, size_t dwSize) + { + if (memory) { + // All this must be redesigned + msync((char*)memory, dwSize, MS_SYNC); + return (munmap((char*)memory, dwSize) < 0) ? true : false; + } else + return false; + + } // end of CloseMemMap + +#endif // UNIX |