X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/578bfd0aed2ec993f4ad85fa6a7094a852261422..8953292ef197b80c16d08b31830945fb7ac9ff8d:/apt-pkg/contrib/mmap.cc diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc index 85cac1cca..e395e6cc7 100644 --- a/apt-pkg/contrib/mmap.cc +++ b/apt-pkg/contrib/mmap.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: mmap.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $ +// $Id: mmap.cc,v 1.22 2001/05/27 05:19:30 jgg Exp $ /* ###################################################################### MMap Class - Provides 'real' mmap or a faked mmap using read(). @@ -21,13 +21,18 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/mmap.h" +#endif + #define _BSD_SOURCE -#include -#include +#include +#include + +#include #include #include -#include #include #include /*}}}*/ @@ -35,11 +40,19 @@ // MMap::MMap - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -MMap::MMap(File &F,unsigned long Flags) : Fd(F), Flags(Flags), iSize(0), +MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0), Base(0) { if ((Flags & NoImmMap) != NoImmMap) - Map(); + Map(F); +} + /*}}}*/ +// MMap::MMap - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +MMap::MMap(unsigned long Flags) : Flags(Flags), iSize(0), + Base(0) +{ } /*}}}*/ // MMap::~MMap - Destructor /*{{{*/ @@ -47,13 +60,13 @@ MMap::MMap(File &F,unsigned long Flags) : Fd(F), Flags(Flags), iSize(0), /* */ MMap::~MMap() { - Close(true); + Close(); } /*}}}*/ // MMap::Map - Perform the mapping /*{{{*/ // --------------------------------------------------------------------- /* */ -bool MMap::Map() +bool MMap::Map(FileFd &Fd) { iSize = Fd.Size(); @@ -65,10 +78,13 @@ bool MMap::Map() if ((Flags & Public) != Public) Map = MAP_PRIVATE; + if (iSize == 0) + return _error->Error(_("Can't mmap an empty file")); + // Map it. Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0); if (Base == (void *)-1) - return _error->Errno("mmap","Couldn't make mmap of %u bytes",iSize); + return _error->Errno("mmap",_("Couldn't make mmap of %lu bytes"),iSize); return true; } @@ -76,30 +92,36 @@ bool MMap::Map() // MMap::Close - Close the map /*{{{*/ // --------------------------------------------------------------------- /* */ -bool MMap::Close(bool DoClose) +bool MMap::Close(bool DoSync) { - if (Fd.IsOpen() == false) + if ((Flags & UnMapped) == UnMapped || Base == 0 || iSize == 0) return true; - - Sync(); + + if (DoSync == true) + Sync(); if (munmap((char *)Base,iSize) != 0) _error->Warning("Unable to munmap"); iSize = 0; - if (DoClose == true) - Fd.Close(); + Base = 0; return true; } /*}}}*/ // MMap::Sync - Syncronize the map with the disk /*{{{*/ // --------------------------------------------------------------------- -/* */ +/* This is done in syncronous mode - the docs indicate that this will + not return till all IO is complete */ bool MMap::Sync() { - if ((Flags & ReadOnly) == ReadOnly) + if ((Flags & UnMapped) == UnMapped) + return true; + +#ifdef _POSIX_SYNCHRONIZED_IO + if ((Flags & ReadOnly) != ReadOnly) if (msync((char *)Base,iSize,MS_SYNC) != 0) - return _error->Error("msync","Unable to write mmap"); + return _error->Errno("msync","Unable to write mmap"); +#endif return true; } /*}}}*/ @@ -108,9 +130,15 @@ bool MMap::Sync() /* */ bool MMap::Sync(unsigned long Start,unsigned long Stop) { - if ((Flags & ReadOnly) == ReadOnly) - if (msync((char *)Base+(int)(Start/PAGE_SIZE)*PAGE_SIZE,Stop - Start,MS_SYNC) != 0) - return _error->Error("msync","Unable to write mmap"); + if ((Flags & UnMapped) == UnMapped) + return true; + +#ifdef _POSIX_SYNCHRONIZED_IO + unsigned long PSize = sysconf(_SC_PAGESIZE); + if ((Flags & ReadOnly) != ReadOnly) + if (msync((char *)Base+(int)(Start/PSize)*PSize,Stop - Start,MS_SYNC) != 0) + return _error->Errno("msync","Unable to write mmap"); +#endif return true; } /*}}}*/ @@ -118,38 +146,70 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop) // DynamicMMap::DynamicMMap - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -DynamicMMap::DynamicMMap(File &F,unsigned long Flags,unsigned long WorkSpace) : - MMap(F,Flags | NoImmMap), WorkSpace(WorkSpace) +DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) : + MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(WorkSpace) { - unsigned long EndOfFile = Fd.Size(); - Fd.Seek(WorkSpace); - char C = 0; - Fd.Write(&C,sizeof(C)); - Map(); + if (_error->PendingError() == true) + return; + + unsigned long EndOfFile = Fd->Size(); + if (EndOfFile > WorkSpace) + WorkSpace = EndOfFile; + else if(WorkSpace > 0) + { + Fd->Seek(WorkSpace - 1); + char C = 0; + Fd->Write(&C,sizeof(C)); + } + + Map(F); iSize = EndOfFile; } /*}}}*/ +// DynamicMMap::DynamicMMap - Constructor for a non-file backed map /*{{{*/ +// --------------------------------------------------------------------- +/* This is just a fancy malloc really.. */ +DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long WorkSpace) : + MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace) +{ + if (_error->PendingError() == true) + return; + + Base = new unsigned char[WorkSpace]; + memset(Base,0,WorkSpace); + iSize = 0; +} + /*}}}*/ // DynamicMMap::~DynamicMMap - Destructor /*{{{*/ // --------------------------------------------------------------------- /* We truncate the file to the size of the memory data set */ DynamicMMap::~DynamicMMap() { + if (Fd == 0) + { + delete [] (unsigned char *)Base; + return; + } + unsigned long EndOfFile = iSize; + iSize = WorkSpace; Close(false); - ftruncate(Fd.Fd(),EndOfFile); - Fd.Close(); + ftruncate(Fd->Fd(),EndOfFile); } /*}}}*/ // DynamicMMap::RawAllocate - Allocate a raw chunk of unaligned space /*{{{*/ // --------------------------------------------------------------------- -/* */ -unsigned long DynamicMMap::RawAllocate(unsigned long Size) +/* This allocates a block of memory aligned to the given size */ +unsigned long DynamicMMap::RawAllocate(unsigned long Size,unsigned long Aln) { unsigned long Result = iSize; - iSize += Size; + if (Aln != 0) + Result += Aln - (iSize%Aln); + + iSize = Result + Size; // Just in case error check - if (Result > WorkSpace) + if (Result + Size > WorkSpace) { _error->Error("Dynamic MMap ran out of room"); return 0; @@ -194,12 +254,12 @@ unsigned long DynamicMMap::Allocate(unsigned long ItemSize) if (I->Count == 0) { I->Count = 20*1024/ItemSize; - I->Start = RawAllocate(I->Count*ItemSize); + I->Start = RawAllocate(I->Count*ItemSize,ItemSize); } - + I->Count--; unsigned long Result = I->Start; - I->Start += ItemSize; + I->Start += ItemSize; return Result/ItemSize; } /*}}}*/ @@ -211,13 +271,13 @@ unsigned long DynamicMMap::WriteString(const char *String, { unsigned long Result = iSize; // Just in case error check - if (Result > WorkSpace) + if (Result + Len > WorkSpace) { _error->Error("Dynamic MMap ran out of room"); return 0; } - if (Len == 0) + if (Len == (unsigned long)-1) Len = strlen(String); iSize += Len + 1; memcpy((char *)Base + Result,String,Len);