summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/contrib')
-rw-r--r--apt-pkg/contrib/configuration.cc24
-rw-r--r--apt-pkg/contrib/configuration.h37
-rw-r--r--apt-pkg/contrib/fileutl.cc84
-rw-r--r--apt-pkg/contrib/fileutl.h5
-rw-r--r--apt-pkg/contrib/mmap.cc127
-rw-r--r--apt-pkg/contrib/mmap.h10
6 files changed, 207 insertions, 80 deletions
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index aaa669ffc..7588b041c 100644
--- a/apt-pkg/contrib/configuration.cc
+++ b/apt-pkg/contrib/configuration.cc
@@ -79,7 +79,7 @@ Configuration::~Configuration()
/* This will lookup a single item by name below another item. It is a
helper function for the main lookup function */
Configuration::Item *Configuration::Lookup(Item *Head,const char *S,
- unsigned long Len,bool Create)
+ unsigned long const &Len,bool const &Create)
{
int Res = 1;
Item *I = Head->Child;
@@ -112,7 +112,7 @@ Configuration::Item *Configuration::Lookup(Item *Head,const char *S,
// ---------------------------------------------------------------------
/* This performs a fully scoped lookup of a given name, possibly creating
new items */
-Configuration::Item *Configuration::Lookup(const char *Name,bool Create)
+Configuration::Item *Configuration::Lookup(const char *Name,bool const &Create)
{
if (Name == 0)
return Root->Child;
@@ -239,7 +239,7 @@ vector<string> Configuration::FindVector(const char *Name) const
// Configuration::FindI - Find an integer value /*{{{*/
// ---------------------------------------------------------------------
/* */
-int Configuration::FindI(const char *Name,int Default) const
+int Configuration::FindI(const char *Name,int const &Default) const
{
const Item *Itm = Lookup(Name);
if (Itm == 0 || Itm->Value.empty() == true)
@@ -256,7 +256,7 @@ int Configuration::FindI(const char *Name,int Default) const
// Configuration::FindB - Find a boolean type /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool Configuration::FindB(const char *Name,bool Default) const
+bool Configuration::FindB(const char *Name,bool const &Default) const
{
const Item *Itm = Lookup(Name);
if (Itm == 0 || Itm->Value.empty() == true)
@@ -332,7 +332,7 @@ void Configuration::Set(const char *Name,const string &Value)
// Configuration::Set - Set an integer value /*{{{*/
// ---------------------------------------------------------------------
/* */
-void Configuration::Set(const char *Name,int Value)
+void Configuration::Set(const char *Name,int const &Value)
{
Item *Itm = Lookup(Name,true);
if (Itm == 0)
@@ -345,7 +345,7 @@ void Configuration::Set(const char *Name,int Value)
// Configuration::Clear - Clear an single value from a list /*{{{*/
// ---------------------------------------------------------------------
/* */
-void Configuration::Clear(const string Name, int Value)
+void Configuration::Clear(string const &Name, int const &Value)
{
char S[300];
snprintf(S,sizeof(S),"%i",Value);
@@ -355,7 +355,7 @@ void Configuration::Clear(const string Name, int Value)
// Configuration::Clear - Clear an single value from a list /*{{{*/
// ---------------------------------------------------------------------
/* */
-void Configuration::Clear(const string Name, string Value)
+void Configuration::Clear(string const &Name, string const &Value)
{
Item *Top = Lookup(Name.c_str(),false);
if (Top == 0 || Top->Child == 0)
@@ -386,7 +386,7 @@ void Configuration::Clear(const string Name, string Value)
// Configuration::Clear - Clear an entire tree /*{{{*/
// ---------------------------------------------------------------------
/* */
-void Configuration::Clear(string Name)
+void Configuration::Clear(string const &Name)
{
Item *Top = Lookup(Name.c_str(),false);
if (Top == 0)
@@ -501,8 +501,8 @@ string Configuration::Item::FullTag(const Item *Stop) const
sections like 'zone "foo.org" { .. };' This causes each section to be
added in with a tag like "zone::foo.org" instead of being split
tag/value. AsSectional enables Sectional parsing.*/
-bool ReadConfigFile(Configuration &Conf,const string &FName,bool AsSectional,
- unsigned Depth)
+bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectional,
+ unsigned const &Depth)
{
// Open the stream for reading
ifstream F(FName.c_str(),ios::in);
@@ -830,9 +830,9 @@ bool ReadConfigFile(Configuration &Conf,const string &FName,bool AsSectional,
// ---------------------------------------------------------------------
/* */
bool ReadConfigDir(Configuration &Conf,const string &Dir,
- bool AsSectional, unsigned Depth)
+ bool const &AsSectional, unsigned const &Depth)
{
- vector<string> const List = GetListOfFilesInDir(Dir, "", true);
+ vector<string> const List = GetListOfFilesInDir(Dir, "conf", true, true);
// Read the files
for (vector<string>::const_iterator I = List.begin(); I != List.end(); I++)
diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h
index e2da83f5b..2494c1d7c 100644
--- a/apt-pkg/contrib/configuration.h
+++ b/apt-pkg/contrib/configuration.h
@@ -58,8 +58,8 @@ class Configuration
Item *Root;
bool ToFree;
- Item *Lookup(Item *Head,const char *S,unsigned long Len,bool Create);
- Item *Lookup(const char *Name,bool Create);
+ Item *Lookup(Item *Head,const char *S,unsigned long const &Len,bool const &Create);
+ Item *Lookup(const char *Name,const bool &Create);
inline const Item *Lookup(const char *Name) const
{
return ((Configuration *)this)->Lookup(Name,false);
@@ -68,32 +68,33 @@ class Configuration
public:
string Find(const char *Name,const char *Default = 0) const;
- string Find(const string Name,const char *Default = 0) const {return Find(Name.c_str(),Default);};
+ string Find(string const &Name,const char *Default = 0) const {return Find(Name.c_str(),Default);};
+ string Find(string const &Name, string const &Default) const {return Find(Name.c_str(),Default.c_str());};
string FindFile(const char *Name,const char *Default = 0) const;
string FindDir(const char *Name,const char *Default = 0) const;
- std::vector<string> FindVector(const string &Name) const;
+ std::vector<string> FindVector(string const &Name) const;
std::vector<string> FindVector(const char *Name) const;
- int FindI(const char *Name,int Default = 0) const;
- int FindI(const string Name,int Default = 0) const {return FindI(Name.c_str(),Default);};
- bool FindB(const char *Name,bool Default = false) const;
- bool FindB(const string Name,bool Default = false) const {return FindB(Name.c_str(),Default);};
+ int FindI(const char *Name,int const &Default = 0) const;
+ int FindI(string const &Name,int const &Default = 0) const {return FindI(Name.c_str(),Default);};
+ bool FindB(const char *Name,bool const &Default = false) const;
+ bool FindB(string const &Name,bool const &Default = false) const {return FindB(Name.c_str(),Default);};
string FindAny(const char *Name,const char *Default = 0) const;
- inline void Set(const string Name,string Value) {Set(Name.c_str(),Value);};
+ inline void Set(const string &Name,const string &Value) {Set(Name.c_str(),Value);};
void CndSet(const char *Name,const string &Value);
void Set(const char *Name,const string &Value);
- void Set(const char *Name,int Value);
+ void Set(const char *Name,const int &Value);
- inline bool Exists(const string Name) const {return Exists(Name.c_str());};
+ inline bool Exists(const string &Name) const {return Exists(Name.c_str());};
bool Exists(const char *Name) const;
bool ExistsAny(const char *Name) const;
// clear a whole tree
- void Clear(const string Name);
+ void Clear(const string &Name);
// remove a certain value from a list (e.g. the list of "APT::Keep-Fds")
- void Clear(const string List, string Value);
- void Clear(const string List, int Value);
+ void Clear(string const &List, string const &Value);
+ void Clear(string const &List, int const &Value);
inline const Item *Tree(const char *Name) const {return Lookup(Name);};
@@ -108,11 +109,11 @@ class Configuration
extern Configuration *_config;
bool ReadConfigFile(Configuration &Conf,const string &FName,
- bool AsSectional = false,
- unsigned Depth = 0);
+ bool const &AsSectional = false,
+ unsigned const &Depth = 0);
bool ReadConfigDir(Configuration &Conf,const string &Dir,
- bool AsSectional = false,
- unsigned Depth = 0);
+ bool const &AsSectional = false,
+ unsigned const &Depth = 0);
#endif
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index cce8a4512..da32983f1 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -202,8 +202,37 @@ bool FileExists(string File)
/* If an extension is given only files with this extension are included
in the returned vector, otherwise every "normal" file is included. */
std::vector<string> GetListOfFilesInDir(string const &Dir, string const &Ext,
- bool const &SortList)
+ bool const &SortList)
{
+ return GetListOfFilesInDir(Dir, Ext, SortList, false);
+}
+std::vector<string> GetListOfFilesInDir(string const &Dir, string const &Ext,
+ bool const &SortList, bool const &AllowNoExt)
+{
+ std::vector<string> ext;
+ ext.reserve(2);
+ if (Ext.empty() == false)
+ ext.push_back(Ext);
+ if (AllowNoExt == true && ext.empty() == false)
+ ext.push_back("");
+ return GetListOfFilesInDir(Dir, ext, SortList);
+}
+std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> const &Ext,
+ bool const &SortList)
+{
+ // Attention debuggers: need to be set with the environment config file!
+ bool const Debug = _config->FindB("Debug::GetListOfFilesInDir", false);
+ if (Debug == true)
+ {
+ std::clog << "Accept in " << Dir << " only files with the following " << Ext.size() << " extensions:" << std::endl;
+ if (Ext.empty() == true)
+ std::clog << "\tNO extension" << std::endl;
+ else
+ for (std::vector<string>::const_iterator e = Ext.begin();
+ e != Ext.end(); ++e)
+ std::clog << '\t' << (e->empty() == true ? "NO" : *e) << " extension" << std::endl;
+ }
+
std::vector<string> List;
DIR *D = opendir(Dir.c_str());
if (D == 0)
@@ -214,28 +243,73 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, string const &Ext,
for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D))
{
+ // skip "hidden" files
if (Ent->d_name[0] == '.')
continue;
- if (Ext.empty() == false && flExtension(Ent->d_name) != Ext)
- continue;
+ // check for accepted extension:
+ // no extension given -> periods are bad as hell!
+ // extensions given -> "" extension allows no extension
+ if (Ext.empty() == false)
+ {
+ string d_ext = flExtension(Ent->d_name);
+ if (d_ext == Ent->d_name) // no extension
+ {
+ if (std::find(Ext.begin(), Ext.end(), "") == Ext.end())
+ {
+ if (Debug == true)
+ std::clog << "Bad file: " << Ent->d_name << " → no extension" << std::endl;
+ continue;
+ }
+ }
+ else if (std::find(Ext.begin(), Ext.end(), d_ext) == Ext.end())
+ {
+ if (Debug == true)
+ std::clog << "Bad file: " << Ent->d_name << " → bad extension »" << flExtension(Ent->d_name) << "«" << std::endl;
+ continue;
+ }
+ }
- // Skip bad file names ala run-parts
+ // Skip bad filenames ala run-parts
const char *C = Ent->d_name;
for (; *C != 0; ++C)
if (isalpha(*C) == 0 && isdigit(*C) == 0
- && *C != '_' && *C != '-' && *C != '.')
+ && *C != '_' && *C != '-') {
+ // no required extension -> dot is a bad character
+ if (*C == '.' && Ext.empty() == false)
+ continue;
break;
+ }
+ // we don't reach the end of the name -> bad character included
if (*C != 0)
+ {
+ if (Debug == true)
+ std::clog << "Bad file: " << Ent->d_name << " → bad character »"
+ << *C << "« in filename (period allowed: " << (Ext.empty() ? "no" : "yes") << ")" << std::endl;
continue;
+ }
+
+ // skip filenames which end with a period. These are never valid
+ if (*(C - 1) == '.')
+ {
+ if (Debug == true)
+ std::clog << "Bad file: " << Ent->d_name << " → Period as last character" << std::endl;
+ continue;
+ }
// Make sure it is a file and not something else
string const File = flCombine(Dir,Ent->d_name);
struct stat St;
if (stat(File.c_str(),&St) != 0 || S_ISREG(St.st_mode) == 0)
+ {
+ if (Debug == true)
+ std::clog << "Bad file: " << Ent->d_name << " → stat says not a good file" << std::endl;
continue;
+ }
+ if (Debug == true)
+ std::clog << "Accept file: " << Ent->d_name << " in " << Dir << std::endl;
List.push_back(File);
}
closedir(D);
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index 2807c29d9..85a94898c 100644
--- a/apt-pkg/contrib/fileutl.h
+++ b/apt-pkg/contrib/fileutl.h
@@ -82,8 +82,13 @@ bool RunScripts(const char *Cnf);
bool CopyFile(FileFd &From,FileFd &To);
int GetLock(string File,bool Errors = true);
bool FileExists(string File);
+// FIXME: next ABI-Break: merge the two method-headers
std::vector<string> GetListOfFilesInDir(string const &Dir, string const &Ext,
bool const &SortList);
+std::vector<string> GetListOfFilesInDir(string const &Dir, string const &Ext,
+ bool const &SortList, bool const &AllowNoExt);
+std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> const &Ext,
+ bool const &SortList);
string SafeGetCWD();
void SetCloseExec(int Fd,bool Close);
void SetNonBlock(int Fd,bool Block);
diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc
index 4d5fcf71e..f440f9489 100644
--- a/apt-pkg/contrib/mmap.cc
+++ b/apt-pkg/contrib/mmap.cc
@@ -140,8 +140,10 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
// DynamicMMap::DynamicMMap - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) :
- MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(WorkSpace)
+DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &Workspace,
+ unsigned long const &Grow, unsigned long const &Limit) :
+ MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(Workspace),
+ GrowFactor(Grow), Limit(Limit)
{
if (_error->PendingError() == true)
return;
@@ -165,32 +167,48 @@ DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace)
/* We try here to use mmap to reserve some space - this is much more
cooler than the fallback solution to simply allocate a char array
and could come in handy later than we are able to grow such an mmap */
-DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long WorkSpace) :
- MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace)
+DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long const &WorkSpace,
+ unsigned long const &Grow, unsigned long const &Limit) :
+ MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace),
+ GrowFactor(Grow), Limit(Limit)
{
- if (_error->PendingError() == true)
- return;
+ if (_error->PendingError() == true)
+ return;
+
+ // disable Moveable if we don't grow
+ if (Grow == 0)
+ Flags &= ~Moveable;
+
+#ifndef __linux__
+ // kfreebsd doesn't have mremap, so we use the fallback
+ if ((Flags & Moveable) == Moveable)
+ Flags |= Fallback;
+#endif
#ifdef _POSIX_MAPPED_FILES
- // Set the permissions.
- int Prot = PROT_READ;
- int Map = MAP_PRIVATE | MAP_ANONYMOUS;
- if ((Flags & ReadOnly) != ReadOnly)
- Prot |= PROT_WRITE;
- if ((Flags & Public) == Public)
- Map = MAP_SHARED | MAP_ANONYMOUS;
+ if ((Flags & Fallback) != Fallback) {
+ // Set the permissions.
+ int Prot = PROT_READ;
+ int Map = MAP_PRIVATE | MAP_ANONYMOUS;
+ if ((Flags & ReadOnly) != ReadOnly)
+ Prot |= PROT_WRITE;
+ if ((Flags & Public) == Public)
+ Map = MAP_SHARED | MAP_ANONYMOUS;
- // use anonymous mmap() to get the memory
- Base = (unsigned char*) mmap(0, WorkSpace, Prot, Map, -1, 0);
+ // use anonymous mmap() to get the memory
+ Base = (unsigned char*) mmap(0, WorkSpace, Prot, Map, -1, 0);
- if(Base == MAP_FAILED)
- _error->Errno("DynamicMMap",_("Couldn't make mmap of %lu bytes"),WorkSpace);
-#else
- // fallback to a static allocated space
- Base = new unsigned char[WorkSpace];
- memset(Base,0,WorkSpace);
+ if(Base == MAP_FAILED)
+ _error->Errno("DynamicMMap",_("Couldn't make mmap of %lu bytes"),WorkSpace);
+
+ iSize = 0;
+ return;
+ }
#endif
- iSize = 0;
+ // fallback to a static allocated space
+ Base = new unsigned char[WorkSpace];
+ memset(Base,0,WorkSpace);
+ iSize = 0;
}
/*}}}*/
// DynamicMMap::~DynamicMMap - Destructor /*{{{*/
@@ -311,30 +329,55 @@ unsigned long DynamicMMap::WriteString(const char *String,
/*}}}*/
// DynamicMMap::Grow - Grow the mmap /*{{{*/
// ---------------------------------------------------------------------
-/* This method will try to grow the mmap we currently use. This doesn't
- work most of the time because we can't move the mmap around in the
- memory for now as this would require to adjust quite a lot of pointers
- but why we should not at least try to grow it before we give up? */
-bool DynamicMMap::Grow()
-{
-#if defined(_POSIX_MAPPED_FILES) && defined(__linux__)
- unsigned long newSize = WorkSpace + 1024*1024;
+/* This method is a wrapper around different methods to (try to) grow
+ a mmap (or our char[]-fallback). Encounterable environments:
+ 1. Moveable + !Fallback + linux -> mremap with MREMAP_MAYMOVE
+ 2. Moveable + !Fallback + !linux -> not possible (forbidden by constructor)
+ 3. Moveable + Fallback -> realloc
+ 4. !Moveable + !Fallback + linux -> mremap alone - which will fail in 99,9%
+ 5. !Moveable + !Fallback + !linux -> not possible (forbidden by constructor)
+ 6. !Moveable + Fallback -> not possible
+ [ While Moveable and Fallback stands for the equally named flags and
+ "linux" indicates a linux kernel instead of a freebsd kernel. ]
+ So what you can see here is, that a MMAP which want to be growable need
+ to be moveable to have a real chance but that this method will at least try
+ the nearly impossible 4 to grow it before it finally give up: Never say never. */
+bool DynamicMMap::Grow() {
+ if (Limit != 0 && WorkSpace >= Limit)
+ return _error->Error(_("The size of a MMap has already reached the defined limit of %lu bytes,"
+ "abort the try to grow the MMap."), Limit);
- if(Fd != 0)
- {
- Fd->Seek(newSize - 1);
- char C = 0;
- Fd->Write(&C,sizeof(C));
- }
+ unsigned long const newSize = WorkSpace + 1024*1024;
- Base = mremap(Base, WorkSpace, newSize, 0);
- if(Base == MAP_FAILED)
- return false;
+ if(Fd != 0) {
+ Fd->Seek(newSize - 1);
+ char C = 0;
+ Fd->Write(&C,sizeof(C));
+ }
+ if ((Flags & Fallback) != Fallback) {
+#if defined(_POSIX_MAPPED_FILES) && defined(__linux__)
+ #ifdef MREMAP_MAYMOVE
+ if ((Flags & Moveable) == Moveable)
+ Base = mremap(Base, WorkSpace, newSize, MREMAP_MAYMOVE);
+ else
+ #endif
+ Base = mremap(Base, WorkSpace, newSize, 0);
- WorkSpace = newSize;
- return true;
+ if(Base == MAP_FAILED)
+ return false;
#else
- return false;
+ return false;
#endif
+ } else {
+ if ((Flags & Moveable) != Moveable)
+ return false;
+
+ Base = realloc(Base, newSize);
+ if (Base == NULL)
+ return false;
+ }
+
+ WorkSpace = newSize;
+ return true;
}
/*}}}*/
diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h
index bde62217d..cd2b15ba2 100644
--- a/apt-pkg/contrib/mmap.h
+++ b/apt-pkg/contrib/mmap.h
@@ -50,7 +50,7 @@ class MMap
public:
enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2),
- UnMapped = (1<<3)};
+ UnMapped = (1<<3), Moveable = (1<<4), Fallback = (1 << 5)};
// Simple accessors
inline operator void *() {return Base;};
@@ -82,6 +82,8 @@ class DynamicMMap : public MMap
FileFd *Fd;
unsigned long WorkSpace;
+ unsigned long const GrowFactor;
+ unsigned long const Limit;
Pool *Pools;
unsigned int PoolCount;
@@ -96,8 +98,10 @@ class DynamicMMap : public MMap
inline unsigned long WriteString(const string &S) {return WriteString(S.c_str(),S.length());};
void UsePools(Pool &P,unsigned int Count) {Pools = &P; PoolCount = Count;};
- DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace = 2*1024*1024);
- DynamicMMap(unsigned long Flags,unsigned long WorkSpace = 2*1024*1024);
+ DynamicMMap(FileFd &F,unsigned long Flags,unsigned long const &WorkSpace = 2*1024*1024,
+ unsigned long const &Grow = 1024*1024, unsigned long const &Limit = 0);
+ DynamicMMap(unsigned long Flags,unsigned long const &WorkSpace = 2*1024*1024,
+ unsigned long const &Grow = 1024*1024, unsigned long const &Limit = 0);
virtual ~DynamicMMap();
};