]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/contrib/mmap.cc
Introduce isspace_ascii() for use by parsers
[apt.git] / apt-pkg / contrib / mmap.cc
index 3e6ef3520d2520705ec8eb5aae82b6bb7bc8d51b..4dc851c1bee7aa23bf2cf31ecb5749c83a98e3d3 100644 (file)
    ##################################################################### */
                                                                        /*}}}*/
 // Include Files                                                       /*{{{*/
    ##################################################################### */
                                                                        /*}}}*/
 // Include Files                                                       /*{{{*/
-#define _BSD_SOURCE
+#define _DEFAULT_SOURCE
 #include <config.h>
 
 #include <apt-pkg/mmap.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/fileutl.h>
 #include <config.h>
 
 #include <apt-pkg/mmap.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/fileutl.h>
+#include <apt-pkg/macros.h>
 
 
+#include <string>
 #include <sys/mman.h>
 #include <sys/mman.h>
-#include <sys/stat.h>
 #include <unistd.h>
 #include <unistd.h>
-#include <fcntl.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <cstring>
 #include <stdlib.h>
 #include <errno.h>
 #include <cstring>
@@ -38,7 +38,7 @@
 // ---------------------------------------------------------------------
 /* */
 MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0),
 // ---------------------------------------------------------------------
 /* */
 MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0),
-                     Base(0), SyncToFd(NULL)
+                     Base(nullptr), SyncToFd(nullptr)
 {
    if ((Flags & NoImmMap) != NoImmMap)
       Map(F);
 {
    if ((Flags & NoImmMap) != NoImmMap)
       Map(F);
@@ -48,7 +48,7 @@ MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0),
 // ---------------------------------------------------------------------
 /* */
 MMap::MMap(unsigned long Flags) : Flags(Flags), iSize(0),
 // ---------------------------------------------------------------------
 /* */
 MMap::MMap(unsigned long Flags) : Flags(Flags), iSize(0),
-                     Base(0), SyncToFd(NULL)
+                     Base(nullptr), SyncToFd(nullptr)
 {
 }
                                                                        /*}}}*/
 {
 }
                                                                        /*}}}*/
@@ -84,6 +84,8 @@ bool MMap::Map(FileFd &Fd)
       if ((Flags & ReadOnly) != ReadOnly)
         return _error->Error("Compressed file %s can only be mapped readonly", Fd.Name().c_str());
       Base = malloc(iSize);
       if ((Flags & ReadOnly) != ReadOnly)
         return _error->Error("Compressed file %s can only be mapped readonly", Fd.Name().c_str());
       Base = malloc(iSize);
+      if (unlikely(Base == nullptr))
+        return _error->Errno("MMap-compressed-malloc", _("Couldn't make mmap of %llu bytes"), iSize);
       SyncToFd = new FileFd();
       if (Fd.Seek(0L) == false || Fd.Read(Base, iSize) == false)
         return _error->Error("Compressed file %s can't be read into mmap", Fd.Name().c_str());
       SyncToFd = new FileFd();
       if (Fd.Seek(0L) == false || Fd.Read(Base, iSize) == false)
         return _error->Error("Compressed file %s can't be read into mmap", Fd.Name().c_str());
@@ -92,7 +94,7 @@ bool MMap::Map(FileFd &Fd)
 
    // Map it.
    Base = (Flags & Fallback) ? MAP_FAILED : mmap(0,iSize,Prot,Map,Fd.Fd(),0);
 
    // Map it.
    Base = (Flags & Fallback) ? MAP_FAILED : mmap(0,iSize,Prot,Map,Fd.Fd(),0);
-   if (Base == (void *)-1)
+   if (Base == MAP_FAILED)
    {
       if (errno == ENODEV || errno == EINVAL || (Flags & Fallback))
       {
    {
       if (errno == ENODEV || errno == EINVAL || (Flags & Fallback))
       {
@@ -102,6 +104,8 @@ bool MMap::Map(FileFd &Fd)
         {
            // for readonly, we don't need sync, so make it simple
            Base = malloc(iSize);
         {
            // 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);
         }
            SyncToFd = new FileFd();
            return Fd.Read(Base, iSize);
         }
@@ -111,13 +115,14 @@ bool MMap::Map(FileFd &Fd)
            return _error->Errno("mmap", _("Couldn't duplicate file descriptor %i"), Fd.Fd());
 
         Base = calloc(iSize, 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
         SyncToFd = new FileFd (dupped_fd);
         if (!SyncToFd->Seek(0L) || !SyncToFd->Read(Base, iSize))
            return false;
       }
       else
-        return _error->Errno("mmap",_("Couldn't make mmap of %llu bytes"),
-                             iSize);
+        return _error->Errno("MMap-mmap", _("Couldn't make mmap of %llu bytes"), iSize);
      }
 
    return true;
      }
 
    return true;
@@ -156,11 +161,10 @@ bool MMap::Close(bool DoSync)
 /* This is done in syncronous mode - the docs indicate that this will 
    not return till all IO is complete */
 bool MMap::Sync()
 /* This is done in syncronous mode - the docs indicate that this will 
    not return till all IO is complete */
 bool MMap::Sync()
-{   
+{
    if ((Flags & UnMapped) == UnMapped)
       return true;
    if ((Flags & UnMapped) == UnMapped)
       return true;
-   
-#ifdef _POSIX_SYNCHRONIZED_IO   
+
    if ((Flags & ReadOnly) != ReadOnly)
    {
       if (SyncToFd != NULL)
    if ((Flags & ReadOnly) != ReadOnly)
    {
       if (SyncToFd != NULL)
@@ -170,11 +174,12 @@ bool MMap::Sync()
       }
       else
       {
       }
       else
       {
+#ifdef _POSIX_SYNCHRONIZED_IO
         if (msync((char *)Base, iSize, MS_SYNC) < 0)
            return _error->Errno("msync", _("Unable to synchronize mmap"));
         if (msync((char *)Base, iSize, MS_SYNC) < 0)
            return _error->Errno("msync", _("Unable to synchronize mmap"));
+#endif
       }
    }
       }
    }
-#endif   
    return true;
 }
                                                                        /*}}}*/
    return true;
 }
                                                                        /*}}}*/
@@ -185,9 +190,7 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
 {
    if ((Flags & UnMapped) == UnMapped)
       return true;
 {
    if ((Flags & UnMapped) == UnMapped)
       return true;
-   
-#ifdef _POSIX_SYNCHRONIZED_IO
-   unsigned long long PSize = sysconf(_SC_PAGESIZE);
+
    if ((Flags & ReadOnly) != ReadOnly)
    {
       if (SyncToFd != 0)
    if ((Flags & ReadOnly) != ReadOnly)
    {
       if (SyncToFd != 0)
@@ -198,11 +201,13 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
       }
       else
       {
       }
       else
       {
-        if (msync((char *)Base+(unsigned long long)(Start/PSize)*PSize,Stop - Start,MS_SYNC) < 0)
+#ifdef _POSIX_SYNCHRONIZED_IO
+        unsigned long long const PSize = sysconf(_SC_PAGESIZE);
+        if (msync((char *)Base+(Start/PSize)*PSize, Stop - Start, MS_SYNC) < 0)
            return _error->Errno("msync", _("Unable to synchronize mmap"));
            return _error->Errno("msync", _("Unable to synchronize mmap"));
+#endif
       }
    }
       }
    }
-#endif   
    return true;
 }
                                                                        /*}}}*/
    return true;
 }
                                                                        /*}}}*/
@@ -215,9 +220,6 @@ DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &Work
                MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(Workspace),
                GrowFactor(Grow), Limit(Limit)
 {
                MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(Workspace),
                GrowFactor(Grow), Limit(Limit)
 {
-   if (_error->PendingError() == true)
-      return;
-
    // disable Moveable if we don't grow
    if (Grow == 0)
       this->Flags &= ~Moveable;
    // disable Moveable if we don't grow
    if (Grow == 0)
       this->Flags &= ~Moveable;
@@ -252,9 +254,6 @@ DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long const &WorkSpace,
                MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace),
                GrowFactor(Grow), Limit(Limit)
 {
                MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace),
                GrowFactor(Grow), Limit(Limit)
 {
-       if (_error->PendingError() == true)
-               return;
-
        // disable Moveable if we don't grow
        if (Grow == 0)
                this->Flags &= ~Moveable;
        // disable Moveable if we don't grow
        if (Grow == 0)
                this->Flags &= ~Moveable;
@@ -352,6 +351,12 @@ unsigned long DynamicMMap::RawAllocate(unsigned long long Size,unsigned long Aln
    size in the file. */
 unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
 {
    size in the file. */
 unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
 {
+   if (unlikely(ItemSize == 0))
+   {
+      _error->Fatal("Can't allocate an item of size zero");
+      return 0;
+   }
+
    // Look for a matching pool entry
    Pool *I;
    Pool *Empty = 0;
    // Look for a matching pool entry
    Pool *I;
    Pool *Empty = 0;
@@ -384,12 +389,15 @@ unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
       const unsigned long size = 20*1024;
       I->Count = size/ItemSize;
       Pool* oldPools = Pools;
       const unsigned long size = 20*1024;
       I->Count = size/ItemSize;
       Pool* oldPools = Pools;
+      _error->PushToStack();
       Result = RawAllocate(size,ItemSize);
       Result = RawAllocate(size,ItemSize);
+      bool const newError = _error->PendingError();
+      _error->MergeWithStack();
       if (Pools != oldPools)
         I += Pools - oldPools;
 
       // Does the allocation failed ?
       if (Pools != oldPools)
         I += Pools - oldPools;
 
       // Does the allocation failed ?
-      if (Result == 0 && _error->PendingError())
+      if (Result == 0 && newError)
         return 0;
       I->Start = Result;
    }
         return 0;
       I->Start = Result;
    }
@@ -410,9 +418,12 @@ unsigned long DynamicMMap::WriteString(const char *String,
    if (Len == (unsigned long)-1)
       Len = strlen(String);
 
    if (Len == (unsigned long)-1)
       Len = strlen(String);
 
+   _error->PushToStack();
    unsigned long const Result = RawAllocate(Len+1,0);
    unsigned long const Result = RawAllocate(Len+1,0);
+   bool const newError = _error->PendingError();
+   _error->MergeWithStack();
 
 
-   if (Result == 0 && _error->PendingError())
+   if (Base == NULL || (Result == 0 && newError))
       return 0;
 
    memcpy((char *)Base + Result,String,Len);
       return 0;
 
    memcpy((char *)Base + Result,String,Len);