X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/578bfd0aed2ec993f4ad85fa6a7094a852261422..1979e742ad5e2a0b6e547fbe3f4c4066b5a9bd2e:/apt-pkg/contrib/error.cc diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc index 59d2b8c8b..5fe9bdfce 100644 --- a/apt-pkg/contrib/error.cc +++ b/apt-pkg/contrib/error.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: error.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $ +// $Id: error.cc,v 1.11 2002/03/26 07:38:58 jgg Exp $ /* ###################################################################### Global Erorr Class - Global error mechanism @@ -14,20 +14,59 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/error.h" +#endif + +#include + +#include #include #include -#include +#include #include +#include -#include +#include "config.h" /*}}}*/ -GlobalError *_error = new GlobalError; +using namespace std; + +// Global Error Object /*{{{*/ +/* If the implementation supports posix threads then the accessor function + is compiled to be thread safe otherwise a non-safe version is used. A + Per-Thread error object is maintained in much the same manner as libc + manages errno */ +#if defined(_POSIX_THREADS) && defined(HAVE_PTHREAD) + #include + + static pthread_key_t ErrorKey; + static void ErrorDestroy(void *Obj) {delete (GlobalError *)Obj;}; + static void KeyAlloc() {pthread_key_create(&ErrorKey,ErrorDestroy);}; + + GlobalError *_GetErrorObj() + { + static pthread_once_t Once = PTHREAD_ONCE_INIT; + pthread_once(&Once,KeyAlloc); + + void *Res = pthread_getspecific(ErrorKey); + if (Res == 0) + pthread_setspecific(ErrorKey,Res = new GlobalError); + return (GlobalError *)Res; + } +#else + GlobalError *_GetErrorObj() + { + static GlobalError *Obj = new GlobalError; + return Obj; + } +#endif + /*}}}*/ // GlobalError::GlobalError - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -GlobalError::GlobalError() : PendingFlag(false) +GlobalError::GlobalError() : List(0), PendingFlag(false) { } /*}}}*/ @@ -45,17 +84,44 @@ bool GlobalError::Errno(const char *Function,const char *Description,...) // sprintf the description char S[400]; - vsprintf(S,Description,args); - sprintf(S + strlen(S)," - %s (%i %s)",Function,errno,strerror(errno)); + vsnprintf(S,sizeof(S),Description,args); + snprintf(S + strlen(S),sizeof(S) - strlen(S), + " - %s (%i %s)",Function,errno,strerror(errno)); // Put it on the list - Item Itm; - Itm.Text = S; - Itm.Error = true; - List.push_back(Itm); + Item *Itm = new Item; + Itm->Text = S; + Itm->Error = true; + Insert(Itm); PendingFlag = true; + return false; +} + /*}}}*/ +// GlobalError::WarningE - Get part of the warn string from errno /*{{{*/ +// --------------------------------------------------------------------- +/* Function indicates the stdlib function that failed and Description is + a user string that leads the text. Form is: + Description - Function (errno: strerror) + Carefull of the buffer overrun, sprintf. + */ +bool GlobalError::WarningE(const char *Function,const char *Description,...) +{ + va_list args; + va_start(args,Description); + + // sprintf the description + char S[400]; + vsnprintf(S,sizeof(S),Description,args); + snprintf(S + strlen(S),sizeof(S) - strlen(S)," - %s (%i %s)",Function,errno,strerror(errno)); + + // Put it on the list + Item *Itm = new Item; + Itm->Text = S; + Itm->Error = false; + Insert(Itm); + return false; } /*}}}*/ @@ -69,13 +135,13 @@ bool GlobalError::Error(const char *Description,...) // sprintf the description char S[400]; - vsprintf(S,Description,args); + vsnprintf(S,sizeof(S),Description,args); // Put it on the list - Item Itm; - Itm.Text = S; - Itm.Error = true; - List.push_back(Itm); + Item *Itm = new Item; + Itm->Text = S; + Itm->Error = true; + Insert(Itm); PendingFlag = true; @@ -92,13 +158,13 @@ bool GlobalError::Warning(const char *Description,...) // sprintf the description char S[400]; - vsprintf(S,Description,args); + vsnprintf(S,sizeof(S),Description,args); // Put it on the list - Item Itm; - Itm.Text = S; - Itm.Error = false; - List.push_back(Itm); + Item *Itm = new Item; + Itm->Text = S; + Itm->Error = false; + Insert(Itm); return false; } @@ -109,12 +175,17 @@ bool GlobalError::Warning(const char *Description,...) true if the message is an error. */ bool GlobalError::PopMessage(string &Text) { - bool Ret = List.front().Error; - Text = List.front().Text; - List.erase(List.begin()); - + if (List == 0) + return false; + + bool Ret = List->Error; + Text = List->Text; + Item *Old = List; + List = List->Next; + delete Old; + // This really should check the list to see if only warnings are left.. - if (empty()) + if (List == 0) PendingFlag = false; return Ret; @@ -137,3 +208,30 @@ void GlobalError::DumpErrors() } } /*}}}*/ +// GlobalError::Discard - Discard /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void GlobalError::Discard() +{ + while (List != 0) + { + Item *Old = List; + List = List->Next; + delete Old; + } + + PendingFlag = false; +}; + /*}}}*/ +// GlobalError::Insert - Insert a new item at the end /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void GlobalError::Insert(Item *Itm) +{ + Item **End = &List; + for (Item *I = List; I != 0; I = I->Next) + End = &I->Next; + Itm->Next = *End; + *End = Itm; +} + /*}}}*/