- Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0);
- if (Base == (void *)-1)
- return _error->Errno("mmap",_("Couldn't make mmap of %lu bytes"),iSize);
+ Base = (Flags & Fallback) ? MAP_FAILED : mmap(0,iSize,Prot,Map,Fd.Fd(),0);
+ if (Base == MAP_FAILED)
+ {
+ if (errno == ENODEV || errno == EINVAL || (Flags & Fallback))
+ {
+ // The filesystem doesn't support this particular kind of mmap.
+ // So we allocate a buffer and read the whole file into it.
+ if ((Flags & ReadOnly) == ReadOnly)
+ {
+ // for readonly, we don't need sync, so make it simple
+ Base = malloc(iSize);
+ if (unlikely(Base == nullptr))
+ return _error->Errno("MMap-malloc", _("Couldn't make mmap of %llu bytes"), iSize);
+ SyncToFd = new FileFd();
+ return Fd.Read(Base, iSize);
+ }
+ // FIXME: Writing to compressed fd's ?
+ int const dupped_fd = dup(Fd.Fd());
+ if (dupped_fd == -1)
+ return _error->Errno("mmap", _("Couldn't duplicate file descriptor %i"), Fd.Fd());
+
+ Base = calloc(iSize, 1);
+ if (unlikely(Base == nullptr))
+ return _error->Errno("MMap-calloc", _("Couldn't make mmap of %llu bytes"), iSize);
+ SyncToFd = new FileFd (dupped_fd);
+ if (!SyncToFd->Seek(0L) || !SyncToFd->Read(Base, iSize))
+ return false;
+ }
+ else
+ return _error->Errno("MMap-mmap", _("Couldn't make mmap of %llu bytes"), iSize);
+ }