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 _WIN32
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 /***********************************************************************/
CreateFileMap(PGLOBAL g,LPCSTR filename,MEMMAP * mm,MODE mode,bool del)25 HANDLE 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 
CloseMemMap(LPVOID memory,size_t dwSize)105 bool 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 /***********************************************************************/
CreateFileMap(PGLOBAL g,LPCSTR fileName,MEMMAP * mm,MODE mode,bool del)125 HANDLE 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 
CloseMemMap(void * memory,size_t dwSize)189 bool 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