]> git.saurik.com Git - apt.git/blame - apt-pkg/contrib/error.cc
run-parts. Closes: #94286
[apt.git] / apt-pkg / contrib / error.cc
CommitLineData
578bfd0a
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
b2e465d6 3// $Id: error.cc,v 1.9 2001/02/20 07:03:17 jgg Exp $
578bfd0a
AL
4/* ######################################################################
5
6 Global Erorr Class - Global error mechanism
7
8 We use a simple STL vector to store each error record. A PendingFlag
9 is kept which indicates when the vector contains a Sever error.
10
11 This source is placed in the Public Domain, do with it what you will
12 It was originally written by Jason Gunthorpe.
13
14 ##################################################################### */
15 /*}}}*/
16// Include Files /*{{{*/
6c139d6e 17#ifdef __GNUG__
094a497d 18#pragma implementation "apt-pkg/error.h"
6c139d6e
AL
19#endif
20
6f27a7fc
AL
21#include <apt-pkg/error.h>
22
578bfd0a
AL
23#include <errno.h>
24#include <stdio.h>
25#include <string.h>
26#include <stdarg.h>
6f27a7fc 27#include <unistd.h>
578bfd0a 28
afd9aaf3 29#include "config.h"
578bfd0a
AL
30 /*}}}*/
31
6f27a7fc
AL
32// Global Error Object /*{{{*/
33/* If the implementation supports posix threads then the accessor function
34 is compiled to be thread safe otherwise a non-safe version is used. A
35 Per-Thread error object is maintained in much the same manner as libc
36 manages errno */
b2e465d6 37#if defined(_POSIX_THREADS) && defined(HAVE_PTHREAD)
6f27a7fc
AL
38 #include <pthread.h>
39
40 static pthread_key_t ErrorKey;
41 static void ErrorDestroy(void *Obj) {delete (GlobalError *)Obj;};
42 static void KeyAlloc() {pthread_key_create(&ErrorKey,ErrorDestroy);};
43
44 GlobalError *_GetErrorObj()
45 {
46 static pthread_once_t Once = PTHREAD_ONCE_INIT;
47 pthread_once(&Once,KeyAlloc);
48
49 void *Res = pthread_getspecific(ErrorKey);
50 if (Res == 0)
51 pthread_setspecific(ErrorKey,Res = new GlobalError);
52 return (GlobalError *)Res;
53 }
54#else
55 GlobalError *_GetErrorObj()
56 {
57 static GlobalError *Obj = new GlobalError;
58 return Obj;
59 }
60#endif
61 /*}}}*/
578bfd0a
AL
62
63// GlobalError::GlobalError - Constructor /*{{{*/
64// ---------------------------------------------------------------------
65/* */
6c139d6e 66GlobalError::GlobalError() : List(0), PendingFlag(false)
578bfd0a
AL
67{
68}
69 /*}}}*/
70// GlobalError::Errno - Get part of the error string from errno /*{{{*/
71// ---------------------------------------------------------------------
72/* Function indicates the stdlib function that failed and Description is
73 a user string that leads the text. Form is:
74 Description - Function (errno: strerror)
75 Carefull of the buffer overrun, sprintf.
76 */
77bool GlobalError::Errno(const char *Function,const char *Description,...)
78{
79 va_list args;
80 va_start(args,Description);
81
82 // sprintf the description
83 char S[400];
7f25bdff
AL
84 vsnprintf(S,sizeof(S),Description,args);
85 snprintf(S + strlen(S),sizeof(S) - strlen(S),
86 " - %s (%i %s)",Function,errno,strerror(errno));
578bfd0a
AL
87
88 // Put it on the list
6c139d6e
AL
89 Item *Itm = new Item;
90 Itm->Text = S;
91 Itm->Error = true;
92 Insert(Itm);
578bfd0a
AL
93
94 PendingFlag = true;
95
c5162d56
AL
96 return false;
97}
98 /*}}}*/
99// GlobalError::WarningE - Get part of the warn string from errno /*{{{*/
100// ---------------------------------------------------------------------
101/* Function indicates the stdlib function that failed and Description is
102 a user string that leads the text. Form is:
103 Description - Function (errno: strerror)
104 Carefull of the buffer overrun, sprintf.
105 */
106bool GlobalError::WarningE(const char *Function,const char *Description,...)
107{
108 va_list args;
109 va_start(args,Description);
110
111 // sprintf the description
112 char S[400];
7f25bdff
AL
113 vsnprintf(S,sizeof(S),Description,args);
114 snprintf(S + strlen(S),sizeof(S) - strlen(S)," - %s (%i %s)",Function,errno,strerror(errno));
c5162d56
AL
115
116 // Put it on the list
117 Item *Itm = new Item;
118 Itm->Text = S;
119 Itm->Error = false;
120 Insert(Itm);
121
578bfd0a
AL
122 return false;
123}
124 /*}}}*/
125// GlobalError::Error - Add an error to the list /*{{{*/
126// ---------------------------------------------------------------------
127/* Just vsprintfs and pushes */
128bool GlobalError::Error(const char *Description,...)
129{
130 va_list args;
131 va_start(args,Description);
132
133 // sprintf the description
134 char S[400];
7f25bdff 135 vsnprintf(S,sizeof(S),Description,args);
578bfd0a
AL
136
137 // Put it on the list
6c139d6e
AL
138 Item *Itm = new Item;
139 Itm->Text = S;
140 Itm->Error = true;
141 Insert(Itm);
578bfd0a
AL
142
143 PendingFlag = true;
144
145 return false;
146}
147 /*}}}*/
148// GlobalError::Warning - Add a warning to the list /*{{{*/
149// ---------------------------------------------------------------------
150/* This doesn't set the pending error flag */
151bool GlobalError::Warning(const char *Description,...)
152{
153 va_list args;
154 va_start(args,Description);
155
156 // sprintf the description
157 char S[400];
7f25bdff 158 vsnprintf(S,sizeof(S),Description,args);
578bfd0a
AL
159
160 // Put it on the list
6c139d6e
AL
161 Item *Itm = new Item;
162 Itm->Text = S;
163 Itm->Error = false;
164 Insert(Itm);
578bfd0a
AL
165
166 return false;
167}
168 /*}}}*/
169// GlobalError::PopMessage - Pulls a single message out /*{{{*/
170// ---------------------------------------------------------------------
171/* This should be used in a loop checking empty() each cycle. It returns
172 true if the message is an error. */
173bool GlobalError::PopMessage(string &Text)
174{
6c139d6e
AL
175 if (List == 0)
176 return false;
177
178 bool Ret = List->Error;
179 Text = List->Text;
180 Item *Old = List;
181 List = List->Next;
182 delete Old;
183
578bfd0a 184 // This really should check the list to see if only warnings are left..
6c139d6e 185 if (List == 0)
578bfd0a
AL
186 PendingFlag = false;
187
188 return Ret;
189}
190 /*}}}*/
191// GlobalError::DumpErrors - Dump all of the errors/warns to cerr /*{{{*/
192// ---------------------------------------------------------------------
193/* */
194void GlobalError::DumpErrors()
195{
196 // Print any errors or warnings found
197 string Err;
198 while (empty() == false)
199 {
200 bool Type = PopMessage(Err);
201 if (Type == true)
202 cerr << "E: " << Err << endl;
203 else
204 cerr << "W: " << Err << endl;
205 }
206}
207 /*}}}*/
6c139d6e
AL
208// GlobalError::Discard - Discard /*{{{*/
209// ---------------------------------------------------------------------
210/* */
211void GlobalError::Discard()
212{
213 while (List != 0)
214 {
215 Item *Old = List;
216 List = List->Next;
217 delete Old;
218 }
219
220 PendingFlag = false;
221};
222 /*}}}*/
223// GlobalError::Insert - Insert a new item at the end /*{{{*/
224// ---------------------------------------------------------------------
225/* */
226void GlobalError::Insert(Item *Itm)
227{
228 Item **End = &List;
229 for (Item *I = List; I != 0; I = I->Next)
230 End = &I->Next;
231 Itm->Next = *End;
232 *End = Itm;
233}
234 /*}}}*/