]>
Commit | Line | Data |
---|---|---|
578bfd0a AL |
1 | // -*- mode: cpp; mode: fold -*- |
2 | // Description /*{{{*/ | |
0db4a45b | 3 | // $Id: mmap.cc,v 1.22 2001/05/27 05:19:30 jgg Exp $ |
578bfd0a AL |
4 | /* ###################################################################### |
5 | ||
6 | MMap Class - Provides 'real' mmap or a faked mmap using read(). | |
7 | ||
8 | MMap cover class. | |
9 | ||
10 | Some broken versions of glibc2 (libc6) have a broken definition | |
11 | of mmap that accepts a char * -- all other systems (and libc5) use | |
12 | void *. We can't safely do anything here that would be portable, so | |
13 | libc6 generates warnings -- which should be errors, g++ isn't properly | |
14 | strict. | |
15 | ||
578bfd0a AL |
16 | ##################################################################### */ |
17 | /*}}}*/ | |
18 | // Include Files /*{{{*/ | |
f9d8a915 | 19 | #define _DEFAULT_SOURCE |
ea542140 DK |
20 | #include <config.h> |
21 | ||
094a497d AL |
22 | #include <apt-pkg/mmap.h> |
23 | #include <apt-pkg/error.h> | |
472ff00e | 24 | #include <apt-pkg/fileutl.h> |
453b82a3 | 25 | #include <apt-pkg/macros.h> |
578bfd0a | 26 | |
453b82a3 | 27 | #include <string> |
578bfd0a | 28 | #include <sys/mman.h> |
578bfd0a | 29 | #include <unistd.h> |
13eb93fc | 30 | #include <stdlib.h> |
06afffcc | 31 | #include <errno.h> |
4f333a8b | 32 | #include <cstring> |
ea542140 DK |
33 | |
34 | #include <apti18n.h> | |
35 | /*}}}*/ | |
578bfd0a AL |
36 | |
37 | // MMap::MMap - Constructor /*{{{*/ | |
38 | // --------------------------------------------------------------------- | |
39 | /* */ | |
2d11135a | 40 | MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0), |
6789e01e | 41 | Base(nullptr), SyncToFd(nullptr) |
578bfd0a | 42 | { |
2d11135a AL |
43 | Map(F); |
44 | } | |
45 | /*}}}*/ | |
46 | // MMap::MMap - Constructor /*{{{*/ | |
47 | // --------------------------------------------------------------------- | |
48 | /* */ | |
49 | MMap::MMap(unsigned long Flags) : Flags(Flags), iSize(0), | |
6789e01e | 50 | Base(nullptr), SyncToFd(nullptr) |
2d11135a | 51 | { |
578bfd0a AL |
52 | } |
53 | /*}}}*/ | |
54 | // MMap::~MMap - Destructor /*{{{*/ | |
55 | // --------------------------------------------------------------------- | |
56 | /* */ | |
57 | MMap::~MMap() | |
58 | { | |
2d11135a | 59 | Close(); |
578bfd0a AL |
60 | } |
61 | /*}}}*/ | |
62 | // MMap::Map - Perform the mapping /*{{{*/ | |
63 | // --------------------------------------------------------------------- | |
64 | /* */ | |
2d11135a | 65 | bool MMap::Map(FileFd &Fd) |
578bfd0a AL |
66 | { |
67 | iSize = Fd.Size(); | |
699b209e | 68 | |
578bfd0a AL |
69 | // Set the permissions. |
70 | int Prot = PROT_READ; | |
71 | int Map = MAP_SHARED; | |
72 | if ((Flags & ReadOnly) != ReadOnly) | |
73 | Prot |= PROT_WRITE; | |
74 | if ((Flags & Public) != Public) | |
75 | Map = MAP_PRIVATE; | |
76 | ||
b35d2f5f | 77 | if (iSize == 0) |
b2e465d6 | 78 | return _error->Error(_("Can't mmap an empty file")); |
032bd56f DK |
79 | |
80 | // We can't mmap compressed fd's directly, so we need to read it completely | |
81 | if (Fd.IsCompressed() == true) | |
82 | { | |
83 | if ((Flags & ReadOnly) != ReadOnly) | |
84 | return _error->Error("Compressed file %s can only be mapped readonly", Fd.Name().c_str()); | |
7899a133 | 85 | Base = malloc(iSize); |
6789e01e DK |
86 | if (unlikely(Base == nullptr)) |
87 | return _error->Errno("MMap-compressed-malloc", _("Couldn't make mmap of %llu bytes"), iSize); | |
6bae2c51 | 88 | SyncToFd = new FileFd(); |
032bd56f | 89 | if (Fd.Seek(0L) == false || Fd.Read(Base, iSize) == false) |
b711c01e | 90 | return _error->Error("Compressed file %s can't be read into mmap", Fd.Name().c_str()); |
032bd56f DK |
91 | return true; |
92 | } | |
93 | ||
578bfd0a | 94 | // Map it. |
7899a133 | 95 | Base = (Flags & Fallback) ? MAP_FAILED : mmap(0,iSize,Prot,Map,Fd.Fd(),0); |
6789e01e | 96 | if (Base == MAP_FAILED) |
06afffcc | 97 | { |
7899a133 | 98 | if (errno == ENODEV || errno == EINVAL || (Flags & Fallback)) |
06afffcc DK |
99 | { |
100 | // The filesystem doesn't support this particular kind of mmap. | |
101 | // So we allocate a buffer and read the whole file into it. | |
699b209e DK |
102 | if ((Flags & ReadOnly) == ReadOnly) |
103 | { | |
104 | // for readonly, we don't need sync, so make it simple | |
7899a133 | 105 | Base = malloc(iSize); |
6789e01e DK |
106 | if (unlikely(Base == nullptr)) |
107 | return _error->Errno("MMap-malloc", _("Couldn't make mmap of %llu bytes"), iSize); | |
fbda0ee9 | 108 | SyncToFd = new FileFd(); |
699b209e DK |
109 | return Fd.Read(Base, iSize); |
110 | } | |
111 | // FIXME: Writing to compressed fd's ? | |
06afffcc DK |
112 | int const dupped_fd = dup(Fd.Fd()); |
113 | if (dupped_fd == -1) | |
114 | return _error->Errno("mmap", _("Couldn't duplicate file descriptor %i"), Fd.Fd()); | |
115 | ||
7899a133 | 116 | Base = calloc(iSize, 1); |
6789e01e DK |
117 | if (unlikely(Base == nullptr)) |
118 | return _error->Errno("MMap-calloc", _("Couldn't make mmap of %llu bytes"), iSize); | |
06afffcc DK |
119 | SyncToFd = new FileFd (dupped_fd); |
120 | if (!SyncToFd->Seek(0L) || !SyncToFd->Read(Base, iSize)) | |
121 | return false; | |
122 | } | |
123 | else | |
6789e01e | 124 | return _error->Errno("MMap-mmap", _("Couldn't make mmap of %llu bytes"), iSize); |
06afffcc | 125 | } |
578bfd0a AL |
126 | |
127 | return true; | |
128 | } | |
129 | /*}}}*/ | |
130 | // MMap::Close - Close the map /*{{{*/ | |
131 | // --------------------------------------------------------------------- | |
132 | /* */ | |
2d11135a | 133 | bool MMap::Close(bool DoSync) |
578bfd0a | 134 | { |
2a79d5b5 | 135 | if ((Flags & UnMapped) == UnMapped || validData() == false || iSize == 0) |
578bfd0a | 136 | return true; |
2d11135a | 137 | |
1164783d AL |
138 | if (DoSync == true) |
139 | Sync(); | |
06afffcc DK |
140 | |
141 | if (SyncToFd != NULL) | |
142 | { | |
7899a133 | 143 | free(Base); |
06afffcc DK |
144 | delete SyncToFd; |
145 | SyncToFd = NULL; | |
146 | } | |
147 | else | |
148 | { | |
149 | if (munmap((char *)Base, iSize) != 0) | |
150 | _error->WarningE("mmap", _("Unable to close mmap")); | |
151 | } | |
152 | ||
578bfd0a | 153 | iSize = 0; |
b2e465d6 | 154 | Base = 0; |
578bfd0a AL |
155 | return true; |
156 | } | |
157 | /*}}}*/ | |
158 | // MMap::Sync - Syncronize the map with the disk /*{{{*/ | |
159 | // --------------------------------------------------------------------- | |
0149949b AL |
160 | /* This is done in syncronous mode - the docs indicate that this will |
161 | not return till all IO is complete */ | |
578bfd0a | 162 | bool MMap::Sync() |
3ac981df | 163 | { |
2d11135a AL |
164 | if ((Flags & UnMapped) == UnMapped) |
165 | return true; | |
3ac981df | 166 | |
1164783d | 167 | if ((Flags & ReadOnly) != ReadOnly) |
06afffcc DK |
168 | { |
169 | if (SyncToFd != NULL) | |
170 | { | |
171 | if (!SyncToFd->Seek(0) || !SyncToFd->Write(Base, iSize)) | |
172 | return false; | |
173 | } | |
174 | else | |
175 | { | |
3ac981df | 176 | #ifdef _POSIX_SYNCHRONIZED_IO |
06afffcc DK |
177 | if (msync((char *)Base, iSize, MS_SYNC) < 0) |
178 | return _error->Errno("msync", _("Unable to synchronize mmap")); | |
3ac981df | 179 | #endif |
06afffcc DK |
180 | } |
181 | } | |
578bfd0a AL |
182 | return true; |
183 | } | |
184 | /*}}}*/ | |
185 | // MMap::Sync - Syncronize a section of the file to disk /*{{{*/ | |
186 | // --------------------------------------------------------------------- | |
187 | /* */ | |
188 | bool MMap::Sync(unsigned long Start,unsigned long Stop) | |
189 | { | |
2d11135a AL |
190 | if ((Flags & UnMapped) == UnMapped) |
191 | return true; | |
3ac981df | 192 | |
1164783d | 193 | if ((Flags & ReadOnly) != ReadOnly) |
06afffcc DK |
194 | { |
195 | if (SyncToFd != 0) | |
196 | { | |
197 | if (!SyncToFd->Seek(0) || | |
198 | !SyncToFd->Write (((char *)Base)+Start, Stop-Start)) | |
199 | return false; | |
200 | } | |
201 | else | |
202 | { | |
3ac981df | 203 | #ifdef _POSIX_SYNCHRONIZED_IO |
e3348f47 | 204 | unsigned long long const PSize = sysconf(_SC_PAGESIZE); |
e788a834 | 205 | if (msync((char *)Base+(Start/PSize)*PSize, Stop - Start, MS_SYNC) < 0) |
06afffcc | 206 | return _error->Errno("msync", _("Unable to synchronize mmap")); |
3ac981df | 207 | #endif |
06afffcc DK |
208 | } |
209 | } | |
578bfd0a AL |
210 | return true; |
211 | } | |
212 | /*}}}*/ | |
213 | ||
214 | // DynamicMMap::DynamicMMap - Constructor /*{{{*/ | |
215 | // --------------------------------------------------------------------- | |
216 | /* */ | |
d6c4a976 DK |
217 | DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &Workspace, |
218 | unsigned long const &Grow, unsigned long const &Limit) : | |
ca2b6d6d | 219 | MMap(Flags), Fd(&F), WorkSpace(Workspace), |
d6c4a976 | 220 | GrowFactor(Grow), Limit(Limit) |
578bfd0a | 221 | { |
7b15b702 DK |
222 | // disable Moveable if we don't grow |
223 | if (Grow == 0) | |
224 | this->Flags &= ~Moveable; | |
225 | ||
226 | #ifndef __linux__ | |
227 | // kfreebsd doesn't have mremap, so we use the fallback | |
228 | if ((this->Flags & Moveable) == Moveable) | |
229 | this->Flags |= Fallback; | |
230 | #endif | |
231 | ||
650faab0 | 232 | unsigned long long EndOfFile = Fd->Size(); |
b2e465d6 AL |
233 | if (EndOfFile > WorkSpace) |
234 | WorkSpace = EndOfFile; | |
ea92d036 | 235 | else if(WorkSpace > 0) |
b2e465d6 | 236 | { |
ea92d036 | 237 | Fd->Seek(WorkSpace - 1); |
b2e465d6 AL |
238 | char C = 0; |
239 | Fd->Write(&C,sizeof(C)); | |
240 | } | |
241 | ||
2d11135a | 242 | Map(F); |
578bfd0a AL |
243 | iSize = EndOfFile; |
244 | } | |
245 | /*}}}*/ | |
2d11135a AL |
246 | // DynamicMMap::DynamicMMap - Constructor for a non-file backed map /*{{{*/ |
247 | // --------------------------------------------------------------------- | |
f1c6a8ca DK |
248 | /* We try here to use mmap to reserve some space - this is much more |
249 | cooler than the fallback solution to simply allocate a char array | |
250 | and could come in handy later than we are able to grow such an mmap */ | |
d6c4a976 DK |
251 | DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long const &WorkSpace, |
252 | unsigned long const &Grow, unsigned long const &Limit) : | |
ca2b6d6d | 253 | MMap(Flags | UnMapped), Fd(0), WorkSpace(WorkSpace), |
d6c4a976 | 254 | GrowFactor(Grow), Limit(Limit) |
2d11135a | 255 | { |
d6c4a976 DK |
256 | // disable Moveable if we don't grow |
257 | if (Grow == 0) | |
a9fe5928 | 258 | this->Flags &= ~Moveable; |
d6c4a976 DK |
259 | |
260 | #ifndef __linux__ | |
261 | // kfreebsd doesn't have mremap, so we use the fallback | |
a9fe5928 DK |
262 | if ((this->Flags & Moveable) == Moveable) |
263 | this->Flags |= Fallback; | |
d6c4a976 | 264 | #endif |
f1c6a8ca DK |
265 | |
266 | #ifdef _POSIX_MAPPED_FILES | |
a9fe5928 | 267 | if ((this->Flags & Fallback) != Fallback) { |
d6c4a976 DK |
268 | // Set the permissions. |
269 | int Prot = PROT_READ; | |
f895e2ce | 270 | #ifdef MAP_ANONYMOUS |
d6c4a976 | 271 | int Map = MAP_PRIVATE | MAP_ANONYMOUS; |
f895e2ce DK |
272 | #else |
273 | int Map = MAP_PRIVATE | MAP_ANON; | |
274 | #endif | |
a9fe5928 | 275 | if ((this->Flags & ReadOnly) != ReadOnly) |
d6c4a976 | 276 | Prot |= PROT_WRITE; |
a9fe5928 | 277 | if ((this->Flags & Public) == Public) |
f895e2ce | 278 | #ifdef MAP_ANONYMOUS |
d6c4a976 | 279 | Map = MAP_SHARED | MAP_ANONYMOUS; |
f895e2ce DK |
280 | #else |
281 | Map = MAP_SHARED | MAP_ANON; | |
282 | #endif | |
eb162ff7 | 283 | |
d6c4a976 DK |
284 | // use anonymous mmap() to get the memory |
285 | Base = (unsigned char*) mmap(0, WorkSpace, Prot, Map, -1, 0); | |
eb162ff7 | 286 | |
d6c4a976 DK |
287 | if(Base == MAP_FAILED) |
288 | _error->Errno("DynamicMMap",_("Couldn't make mmap of %lu bytes"),WorkSpace); | |
289 | ||
290 | iSize = 0; | |
291 | return; | |
292 | } | |
d5972534 | 293 | #endif |
d6c4a976 | 294 | // fallback to a static allocated space |
7899a133 | 295 | Base = calloc(WorkSpace, 1); |
d6c4a976 | 296 | iSize = 0; |
2d11135a AL |
297 | } |
298 | /*}}}*/ | |
578bfd0a AL |
299 | // DynamicMMap::~DynamicMMap - Destructor /*{{{*/ |
300 | // --------------------------------------------------------------------- | |
301 | /* We truncate the file to the size of the memory data set */ | |
302 | DynamicMMap::~DynamicMMap() | |
303 | { | |
2d11135a AL |
304 | if (Fd == 0) |
305 | { | |
2a79d5b5 | 306 | if (validData() == false) |
26b37f95 | 307 | return; |
f1c6a8ca | 308 | #ifdef _POSIX_MAPPED_FILES |
a67de73e | 309 | munmap(Base, WorkSpace); |
f1c6a8ca | 310 | #else |
7899a133 | 311 | free(Base); |
f1c6a8ca | 312 | #endif |
2d11135a AL |
313 | return; |
314 | } | |
315 | ||
650faab0 | 316 | unsigned long long EndOfFile = iSize; |
1164783d | 317 | iSize = WorkSpace; |
2d11135a | 318 | Close(false); |
3c8cda8b MV |
319 | if(ftruncate(Fd->Fd(),EndOfFile) < 0) |
320 | _error->Errno("ftruncate", _("Failed to truncate file")); | |
578bfd0a AL |
321 | } |
322 | /*}}}*/ | |
323 | // DynamicMMap::RawAllocate - Allocate a raw chunk of unaligned space /*{{{*/ | |
324 | // --------------------------------------------------------------------- | |
f55a958f | 325 | /* This allocates a block of memory aligned to the given size */ |
650faab0 | 326 | unsigned long DynamicMMap::RawAllocate(unsigned long long Size,unsigned long Aln) |
578bfd0a | 327 | { |
650faab0 | 328 | unsigned long long Result = iSize; |
f55a958f AL |
329 | if (Aln != 0) |
330 | Result += Aln - (iSize%Aln); | |
c5f44afc | 331 | |
f55a958f | 332 | iSize = Result + Size; |
c5f44afc | 333 | |
f1c6a8ca DK |
334 | // try to grow the buffer |
335 | while(Result + Size > WorkSpace) | |
578bfd0a | 336 | { |
f1c6a8ca DK |
337 | if(!Grow()) |
338 | { | |
5afa55c6 | 339 | _error->Fatal(_("Dynamic MMap ran out of room. Please increase the size " |
4bd60a02 | 340 | "of APT::Cache-Start. Current value: %lu. (man 5 apt.conf)"), WorkSpace); |
f1c6a8ca DK |
341 | return 0; |
342 | } | |
578bfd0a | 343 | } |
578bfd0a AL |
344 | return Result; |
345 | } | |
346 | /*}}}*/ | |
347 | // DynamicMMap::Allocate - Pooled aligned allocation /*{{{*/ | |
348 | // --------------------------------------------------------------------- | |
349 | /* This allocates an Item of size ItemSize so that it is aligned to its | |
350 | size in the file. */ | |
351 | unsigned long DynamicMMap::Allocate(unsigned long ItemSize) | |
c5f44afc | 352 | { |
62d8a765 DK |
353 | if (unlikely(ItemSize == 0)) |
354 | { | |
355 | _error->Fatal("Can't allocate an item of size zero"); | |
356 | return 0; | |
357 | } | |
358 | ||
578bfd0a AL |
359 | // Look for a matching pool entry |
360 | Pool *I; | |
361 | Pool *Empty = 0; | |
a9fe5928 | 362 | for (I = Pools; I != Pools + PoolCount; ++I) |
578bfd0a AL |
363 | { |
364 | if (I->ItemSize == 0) | |
365 | Empty = I; | |
366 | if (I->ItemSize == ItemSize) | |
367 | break; | |
368 | } | |
578bfd0a AL |
369 | // No pool is allocated, use an unallocated one |
370 | if (I == Pools + PoolCount) | |
371 | { | |
372 | // Woops, we ran out, the calling code should allocate more. | |
373 | if (Empty == 0) | |
374 | { | |
375 | _error->Error("Ran out of allocation pools"); | |
376 | return 0; | |
377 | } | |
378 | ||
379 | I = Empty; | |
380 | I->ItemSize = ItemSize; | |
381 | I->Count = 0; | |
382 | } | |
c5f44afc DK |
383 | |
384 | unsigned long Result = 0; | |
578bfd0a AL |
385 | // Out of space, allocate some more |
386 | if (I->Count == 0) | |
387 | { | |
c5f44afc DK |
388 | const unsigned long size = 20*1024; |
389 | I->Count = size/ItemSize; | |
a9fe5928 | 390 | Pool* oldPools = Pools; |
95278287 | 391 | _error->PushToStack(); |
c5f44afc | 392 | Result = RawAllocate(size,ItemSize); |
95278287 DK |
393 | bool const newError = _error->PendingError(); |
394 | _error->MergeWithStack(); | |
a9fe5928 DK |
395 | if (Pools != oldPools) |
396 | I += Pools - oldPools; | |
397 | ||
c5f44afc | 398 | // Does the allocation failed ? |
95278287 | 399 | if (Result == 0 && newError) |
c5f44afc DK |
400 | return 0; |
401 | I->Start = Result; | |
402 | } | |
403 | else | |
404 | Result = I->Start; | |
f55a958f | 405 | |
578bfd0a | 406 | I->Count--; |
c5f44afc | 407 | I->Start += ItemSize; |
578bfd0a AL |
408 | return Result/ItemSize; |
409 | } | |
410 | /*}}}*/ | |
411 | // DynamicMMap::WriteString - Write a string to the file /*{{{*/ | |
412 | // --------------------------------------------------------------------- | |
60d523e2 | 413 | /* Strings are aligned to 16 bytes */ |
578bfd0a AL |
414 | unsigned long DynamicMMap::WriteString(const char *String, |
415 | unsigned long Len) | |
416 | { | |
6e52073f | 417 | if (Len == (unsigned long)-1) |
578bfd0a | 418 | Len = strlen(String); |
c5f44afc | 419 | |
95278287 | 420 | _error->PushToStack(); |
60d523e2 | 421 | unsigned long Result = RawAllocate(Len+1+sizeof(uint16_t),sizeof(uint16_t)); |
95278287 DK |
422 | bool const newError = _error->PendingError(); |
423 | _error->MergeWithStack(); | |
c5f44afc | 424 | |
95278287 | 425 | if (Base == NULL || (Result == 0 && newError)) |
c5f44afc DK |
426 | return 0; |
427 | ||
60d523e2 JAK |
428 | if (Len >= std::numeric_limits<uint16_t>::max()) |
429 | abort(); | |
430 | ||
431 | uint16_t LenToWrite = Len; | |
432 | memcpy((char *)Base + Result, &LenToWrite, sizeof(LenToWrite)); | |
433 | Result += + sizeof(LenToWrite); | |
434 | ||
578bfd0a AL |
435 | memcpy((char *)Base + Result,String,Len); |
436 | ((char *)Base)[Result + Len] = 0; | |
437 | return Result; | |
438 | } | |
439 | /*}}}*/ | |
f1c6a8ca DK |
440 | // DynamicMMap::Grow - Grow the mmap /*{{{*/ |
441 | // --------------------------------------------------------------------- | |
d6c4a976 DK |
442 | /* This method is a wrapper around different methods to (try to) grow |
443 | a mmap (or our char[]-fallback). Encounterable environments: | |
444 | 1. Moveable + !Fallback + linux -> mremap with MREMAP_MAYMOVE | |
445 | 2. Moveable + !Fallback + !linux -> not possible (forbidden by constructor) | |
446 | 3. Moveable + Fallback -> realloc | |
447 | 4. !Moveable + !Fallback + linux -> mremap alone - which will fail in 99,9% | |
448 | 5. !Moveable + !Fallback + !linux -> not possible (forbidden by constructor) | |
449 | 6. !Moveable + Fallback -> not possible | |
450 | [ While Moveable and Fallback stands for the equally named flags and | |
451 | "linux" indicates a linux kernel instead of a freebsd kernel. ] | |
452 | So what you can see here is, that a MMAP which want to be growable need | |
453 | to be moveable to have a real chance but that this method will at least try | |
454 | the nearly impossible 4 to grow it before it finally give up: Never say never. */ | |
455 | bool DynamicMMap::Grow() { | |
456 | if (Limit != 0 && WorkSpace >= Limit) | |
e3ac3b46 DK |
457 | return _error->Error(_("Unable to increase the size of the MMap as the " |
458 | "limit of %lu bytes is already reached."), Limit); | |
dcdf1ef1 DK |
459 | if (GrowFactor <= 0) |
460 | return _error->Error(_("Unable to increase size of the MMap as automatic growing is disabled by user.")); | |
f1c6a8ca | 461 | |
650faab0 | 462 | unsigned long long const newSize = WorkSpace + GrowFactor; |
f1c6a8ca | 463 | |
d6c4a976 DK |
464 | if(Fd != 0) { |
465 | Fd->Seek(newSize - 1); | |
466 | char C = 0; | |
467 | Fd->Write(&C,sizeof(C)); | |
468 | } | |
a9fe5928 DK |
469 | |
470 | unsigned long const poolOffset = Pools - ((Pool*) Base); | |
471 | ||
d6c4a976 DK |
472 | if ((Flags & Fallback) != Fallback) { |
473 | #if defined(_POSIX_MAPPED_FILES) && defined(__linux__) | |
474 | #ifdef MREMAP_MAYMOVE | |
a9fe5928 | 475 | |
d6c4a976 DK |
476 | if ((Flags & Moveable) == Moveable) |
477 | Base = mremap(Base, WorkSpace, newSize, MREMAP_MAYMOVE); | |
478 | else | |
479 | #endif | |
480 | Base = mremap(Base, WorkSpace, newSize, 0); | |
f1c6a8ca | 481 | |
d6c4a976 DK |
482 | if(Base == MAP_FAILED) |
483 | return false; | |
f1c6a8ca | 484 | #else |
d6c4a976 | 485 | return false; |
f1c6a8ca | 486 | #endif |
d6c4a976 DK |
487 | } else { |
488 | if ((Flags & Moveable) != Moveable) | |
489 | return false; | |
490 | ||
491 | Base = realloc(Base, newSize); | |
492 | if (Base == NULL) | |
493 | return false; | |
e3026ce4 JAK |
494 | else |
495 | /* Set new memory to 0 */ | |
496 | memset((char*)Base + WorkSpace, 0, newSize - WorkSpace); | |
d6c4a976 DK |
497 | } |
498 | ||
a9fe5928 | 499 | Pools =(Pool*) Base + poolOffset; |
d6c4a976 DK |
500 | WorkSpace = newSize; |
501 | return true; | |
f1c6a8ca DK |
502 | } |
503 | /*}}}*/ |