1#include "my_global.h"
2#ifdef UNIX
3#include "osutil.h"
4#include <errno.h>
5#include <stddef.h>
6#else /* WINDOWS */
7//#include <windows.h>
8#include "osutil.h"
9#endif /* WINDOWS */
10#include <stdlib.h>
11#include <stdio.h>
12
13#include "global.h"
14#include "plgdbsem.h"
15#include "maputil.h"
16
17#ifdef __WIN__
18/***********************************************************************/
19/* In Insert mode, just open the file for append. Otherwise */
20/* create the mapping file object. The map handle can be released */
21/* immediately because they will not be used anymore. */
22/* If del is true in DELETE mode, then delete the whole file. */
23/* Returns the file handle that can be used by caller. */
24/***********************************************************************/
25HANDLE CreateFileMap(PGLOBAL g, LPCSTR filename,
26 MEMMAP *mm, MODE mode, bool del)
27 {
28 HANDLE hFile;
29 HANDLE hFileMap;
30 DWORD access, share, disposition;
31
32 memset(mm, 0, sizeof(MEMMAP));
33 *g->Message = '\0';
34
35 switch (mode) {
36 case MODE_READ:
37 access = GENERIC_READ;
38 share = FILE_SHARE_READ;
39 disposition = OPEN_EXISTING;
40 break;
41 case MODE_UPDATE:
42 case MODE_DELETE:
43 access = GENERIC_READ | GENERIC_WRITE;
44 share = 0;
45 disposition = (del) ? TRUNCATE_EXISTING : OPEN_EXISTING;
46 break;
47 case MODE_INSERT:
48 access = GENERIC_WRITE;
49 share = 0;
50 disposition = OPEN_ALWAYS;
51 break;
52 default:
53 sprintf(g->Message, MSG(BAD_FUNC_MODE), "CreateFileMap", mode);
54 return INVALID_HANDLE_VALUE;
55 } // endswitch
56
57 hFile = CreateFile(filename, access, share, NULL, disposition,
58 FILE_ATTRIBUTE_NORMAL, NULL);
59
60 if (hFile != INVALID_HANDLE_VALUE)
61 if (mode != MODE_INSERT) {
62 /*****************************************************************/
63 /* Create the file-mapping object. */
64 /*****************************************************************/
65 access = (mode == MODE_READ) ? PAGE_READONLY : PAGE_READWRITE;
66 hFileMap = CreateFileMapping(hFile, NULL, access, 0, 0, NULL);
67
68 if (!hFileMap) {
69 DWORD ler = GetLastError();
70
71 if (ler && ler != 1006) {
72 sprintf(g->Message, MSG(FILE_MAP_ERROR), filename, ler);
73 CloseHandle(hFile);
74 return INVALID_HANDLE_VALUE;
75 } else {
76 sprintf(g->Message, MSG(FILE_IS_EMPTY), filename);
77 return hFile;
78 } // endif ler
79
80 } // endif hFileMap
81
82 access = (mode == MODE_READ) ? FILE_MAP_READ : FILE_MAP_WRITE;
83
84 if (!(mm->memory = MapViewOfFile(hFileMap, access, 0, 0, 0))) {
85 DWORD ler = GetLastError();
86
87 sprintf(g->Message, "Error %ld in MapViewOfFile %s",
88 ler, filename);
89 CloseHandle(hFile);
90 return INVALID_HANDLE_VALUE;
91 } // endif memory
92
93 // lenH is the high-order word of the file size
94 mm->lenL = GetFileSize(hFile, &mm->lenH);
95 CloseHandle(hFileMap); // Not used anymore
96 } else // MODE_INSERT
97 /*****************************************************************/
98 /* The starting point must be the end of file as for append. */
99 /*****************************************************************/
100 SetFilePointer(hFile, 0, NULL, FILE_END);
101
102 return hFile;
103 } // end of CreateFileMap
104
105bool CloseMemMap(LPVOID memory, size_t dwSize)
106 {
107 return (memory) ? !UnmapViewOfFile(memory) : false;
108 } // end of CloseMemMap
109
110#else /* UNIX */
111// Code to handle Linux and Solaris
112#include <sys/types.h>
113#include <sys/mman.h>
114#include <unistd.h>
115#include <sys/stat.h>
116#include <fcntl.h>
117
118/***********************************************************************/
119/* In Insert mode, just open the file for append. Otherwise */
120/* create the mapping file object. The map handle can be released */
121/* immediately because they will not be used anymore. */
122/* If del is true in DELETE mode, then delete the whole file. */
123/* Returns the file handle that can be used by caller. */
124/***********************************************************************/
125HANDLE CreateFileMap(PGLOBAL g, LPCSTR fileName,
126 MEMMAP *mm, MODE mode, bool del)
127 {
128 unsigned int openMode;
129 int protmode;
130 HANDLE fd;
131 size_t filesize;
132 struct stat st;
133
134 memset(mm, 0, sizeof(MEMMAP));
135 *g->Message = '\0';
136
137 switch (mode) {
138 case MODE_READ:
139 openMode = O_RDONLY;
140 protmode = PROT_READ;
141 break;
142 case MODE_UPDATE:
143 case MODE_DELETE:
144 openMode = (del) ? (O_RDWR | O_TRUNC) : O_RDWR;
145 protmode = PROT_READ | PROT_WRITE;
146 break;
147 case MODE_INSERT:
148 openMode = (O_WRONLY | O_CREAT | O_APPEND);
149 protmode = PROT_WRITE;
150 break;
151 default:
152 sprintf(g->Message, MSG(BAD_FUNC_MODE), "CreateFileMap", mode);
153 return INVALID_HANDLE_VALUE;
154 } // endswitch
155
156 // Try to open the addressed file.
157 fd= global_open(g, MSGID_NONE, fileName, openMode);
158
159 if (fd != INVALID_HANDLE_VALUE && mode != MODE_INSERT) {
160 /* We must know about the size of the file. */
161 if (fstat(fd, &st)) {
162 sprintf(g->Message, MSG(FILE_MAP_ERROR), fileName, errno);
163 close(fd);
164 return INVALID_HANDLE_VALUE;
165 } // endif fstat
166
167 if ((filesize = st.st_size))
168 // Now we are ready to load the file. If mmap() is available we try
169 // this first. If not available or it failed we try to load it.
170 mm->memory = mmap(NULL, filesize, protmode, MAP_SHARED, fd, 0);
171 else
172 mm->memory = 0;
173
174 if (mm->memory != MAP_FAILED) {
175 mm->lenL = (mm->memory != 0) ? filesize : 0;
176 mm->lenH = 0;
177 } else {
178 strcpy(g->Message, "Memory mapping failed");
179 close(fd);
180 return INVALID_HANDLE_VALUE;
181 } // endif memory
182
183 } /* endif fd */
184
185 // mmap() call was successful. ??????????
186 return fd;
187 } // end of CreateFileMap
188
189bool CloseMemMap(void *memory, size_t dwSize)
190 {
191 if (memory) {
192 // All this must be redesigned
193 int rc = msync((char*)memory, dwSize, MS_SYNC);
194 return (munmap((char*)memory, dwSize) < 0) ? true : false;
195 } else
196 return false;
197
198 } // end of CloseMemMap
199
200#endif // UNIX
201