~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSException.cc

Added the PBMS daemon plugin.

(Augen zu und durch!)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2008 PrimeBase Technologies GmbH, Germany
 
2
 *
 
3
 * PrimeBase Media Stream for MySQL
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
18
 *
 
19
 * Original author: Paul McCullagh (H&G2JCtL)
 
20
 * Continued development: Barry Leslie
 
21
 *
 
22
 * 2007-05-20
 
23
 *
 
24
 * The main exception classes
 
25
 *
 
26
 */
 
27
 
 
28
#include "CSConfig.h"
 
29
 
 
30
#include <sys/signal.h>
 
31
#include <limits.h>
 
32
#include <string.h>
 
33
 
 
34
#include "CSGlobal.h"
 
35
#include "CSException.h"
 
36
#include "CSStrUtil.h"
 
37
#include "CSLog.h"
 
38
 
 
39
void CSException::setStackTrace(CSThread *self, const char *stack)
 
40
{
 
41
        char buffer[CS_EXC_CONTEXT_SIZE];
 
42
 
 
43
        self->myException.iStackTrace.setLength(0);
 
44
        if (stack)
 
45
                self->myException.iStackTrace.append(stack);
 
46
        for (int i=self->callTop-1; i>=0; i--) {
 
47
                cs_format_context(CS_EXC_CONTEXT_SIZE, buffer,
 
48
                        self->callStack[i].cs_func, self->callStack[i].cs_file, self->callStack[i].cs_line);
 
49
                self->myException.iStackTrace.append(buffer);
 
50
                self->myException.iStackTrace.append('\n');
 
51
        }
 
52
}
 
53
 
 
54
void CSException::setStackTrace(CSThread *self)
 
55
{
 
56
        setStackTrace(self, NULL);
 
57
}
 
58
 
 
59
const char *CSException::getStackTrace()
 
60
{
 
61
        return iStackTrace.getCString();
 
62
}
 
63
 
 
64
void CSException::log(CSThread *self)
 
65
{
 
66
        CSL.lock();
 
67
        CSL.log(self, CSLog::Error, getContext());
 
68
        CSL.log(self, CSLog::Error, " ");
 
69
        CSL.log(self, CSLog::Error, getMessage());
 
70
        CSL.eol(self, CSLog::Error);
 
71
        CSL.log(self, CSLog::Error, getStackTrace());
 
72
        CSL.unlock();
 
73
}
 
74
 
 
75
void CSException::log(CSThread *self, const char *message)
 
76
{
 
77
        CSL.lock();
 
78
        CSL.log(self, CSLog::Error, message);
 
79
        CSL.eol(self, CSLog::Error);
 
80
        CSL.log(self, CSLog::Error, getContext());
 
81
        CSL.log(self, CSLog::Error, " ");
 
82
        CSL.log(self, CSLog::Error, getMessage());
 
83
        CSL.eol(self, CSLog::Error);
 
84
        CSL.log(self, CSLog::Error, getStackTrace());
 
85
        CSL.unlock();
 
86
}
 
87
 
 
88
void CSException::initException(const char *func, const char *file, int line, int err, const char *message)
 
89
{
 
90
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
91
        iErrorCode = err;
 
92
        cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, message);
 
93
}
 
94
 
 
95
void CSException::initAssertion(const char *func, const char *file, int line, const char *message)
 
96
{
 
97
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
98
        iErrorCode = CS_ERR_ASSERTION;
 
99
        cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, message);
 
100
}
 
101
 
 
102
void CSException::getCoreError(u_int size, char *buffer, int err)
 
103
{
 
104
        const char *message = NULL;
 
105
 
 
106
        switch (err) {
 
107
                case CS_ERR_JUMP_OVERFLOW: message = "Jump stack overflow"; break;
 
108
                case CS_ERR_BAD_ADDRESS: message = "Incorrect network address: %"; break;
 
109
                case CS_ERR_UNKNOWN_SERVICE: message = "Unknown network service: %"; break;
 
110
                case CS_ERR_UNKNOWN_HOST:  message = "Unknown host: %"; break;
 
111
                case CS_ERR_UNKNOWN_METHOD: message = "Unknown HTTP method: %"; break;
 
112
                case CS_ERR_NO_LISTENER: message = "Listening port has been closed"; break;
 
113
                case CS_ERR_RELEASE_OVERFLOW: message = "Release stack overflow"; break;
 
114
                case CS_ERR_IMPL_MISSING: message = "Function %s not implemented"; break;
 
115
                case CS_ERR_BAD_HEADER_MAGIC: message = "Incorrect file type"; break;
 
116
                case CS_ERR_VERSION_TOO_NEW: message = "Incompatible file version"; break;
 
117
        }
 
118
        if (message)
 
119
                cs_strcpy(size, buffer, message);
 
120
        else {
 
121
                cs_strcpy(size, buffer, "Unknown system error ");
 
122
                cs_strcat(size, buffer, err);
 
123
        }
 
124
}
 
125
 
 
126
void CSException::initCoreError(const char *func, const char *file, int line, int err)
 
127
{
 
128
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
129
        iErrorCode = err;
 
130
        getCoreError(CS_EXC_MESSAGE_SIZE, iMessage, err);
 
131
}
 
132
 
 
133
void CSException::initCoreError(const char *func, const char *file, int line, int err, const char *item)
 
134
{
 
135
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
136
        iErrorCode = err;
 
137
        getCoreError(CS_EXC_MESSAGE_SIZE, iMessage, err);
 
138
        cs_replace_string(CS_EXC_MESSAGE_SIZE, iMessage, '%', item);
 
139
}
 
140
 
 
141
void CSException::initOSError(const char *func, const char *file, int line, int err)
 
142
{
 
143
        char *msg;
 
144
 
 
145
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
146
        iErrorCode = err;
 
147
 
 
148
#ifdef XT_WIN
 
149
        if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, iMessage, CS_EXC_MESSAGE_SIZE, NULL)) {
 
150
                char *ptr;
 
151
 
 
152
                ptr = &iMessage[strlen(iMessage)];
 
153
                while (ptr-1 > err_msg) {
 
154
                        if (*(ptr-1) != '\n' && *(ptr-1) != '\r' && *(ptr-1) != '.')
 
155
                                break;
 
156
                        ptr--;
 
157
                }
 
158
                *ptr = 0;
 
159
 
 
160
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, " (");
 
161
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, err);
 
162
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ")");
 
163
                return;
 
164
        }
 
165
#endif
 
166
 
 
167
        msg = strerror(err);
 
168
        if (msg) {
 
169
                cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, msg);
 
170
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, " (");
 
171
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, err);
 
172
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ")");
 
173
        }
 
174
        else {
 
175
                cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "Unknown OS error code ");
 
176
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, err);
 
177
        }
 
178
}
 
179
 
 
180
void CSException::initFileError(const char *func, const char *file, int line, const char *path, int err)
 
181
{
 
182
        initOSError(func, file, line, err);
 
183
        cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ": '");
 
184
        cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, path);
 
185
        cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, "'");
 
186
}
 
187
 
 
188
void CSException::initSignal(const char *func, const char *file, int line, int sig)
 
189
{
 
190
        char *str;
 
191
 
 
192
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
193
        iErrorCode = sig;
 
194
        if (!(str = strsignal(sig))) {
 
195
                cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "Unknown signal ");
 
196
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, sig);
 
197
        }
 
198
        else {
 
199
                cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, str);
 
200
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, " (");
 
201
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, sig);
 
202
                cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ")");
 
203
        }
 
204
}
 
205
 
 
206
void CSException::initEOFError(const char *func, const char *file, int line, const char *path)
 
207
{
 
208
        cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
 
209
        iErrorCode = CS_ERR_EOF;
 
210
        cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "EOF encountered: '");
 
211
        cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, path);
 
212
        cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, "'");
 
213
}
 
214
 
 
215
void CSException::RecordException(const char *func, const char *file, int line, int err, const char *message)
 
216
{
 
217
        CSThread *self;
 
218
 
 
219
        if ((self = CSThread::getSelf())) {
 
220
                if (!self->myException.getErrorCode())
 
221
                        self->myException.initException(func, file, line, err, message);
 
222
        }
 
223
}
 
224
 
 
225
void CSException::ClearException()
 
226
{
 
227
        CSThread *self;
 
228
 
 
229
        if ((self = CSThread::getSelf())) {
 
230
                self->myException.setErrorCode(0);
 
231
        }
 
232
}
 
233
 
 
234
void CSException::throwException(const char *func, const char *file, int line, int err, const char *message, const char *stack)
 
235
{
 
236
        CSThread *self;
 
237
 
 
238
        if ((self = CSThread::getSelf())) {
 
239
                self->myException.initException(func, file, line, err, message);
 
240
                self->myException.setStackTrace(self, stack);
 
241
                self->throwException();
 
242
        }
 
243
        else {
 
244
                CSException e;
 
245
                
 
246
                e.initException(func, file, line, err,message);
 
247
                e.log(NULL, "*** Uncaught error");
 
248
        }
 
249
}
 
250
 
 
251
void CSException::throwException(const char *func, const char *file, int line, int err, const char *message)
 
252
{
 
253
        throwException(func, file, line, err, message, NULL);
 
254
}
 
255
 
 
256
void CSException::throwAssertion(const char *func, const char *file, int line, const char *message)
 
257
{
 
258
        CSThread *self;
 
259
 
 
260
        if ((self = CSThread::getSelf())) {
 
261
                self->myException.initAssertion(func, file, line, message);
 
262
                self->myException.setStackTrace(self);
 
263
                self->logException();
 
264
                self->throwException();
 
265
        }
 
266
        else {
 
267
                CSException e;
 
268
                
 
269
                e.initAssertion(func, file, line, message);
 
270
                e.log(NULL, "*** Uncaught error");
 
271
        }
 
272
}
 
273
 
 
274
void CSException::throwCoreError(const char *func, const char *file, int line, int err)
 
275
{
 
276
        CSThread *self;
 
277
 
 
278
        if ((self = CSThread::getSelf())) {
 
279
                self->myException.initCoreError(func, file, line, err);
 
280
                self->myException.setStackTrace(self);
 
281
                self->throwException();
 
282
        }
 
283
        else {
 
284
                CSException e;
 
285
                
 
286
                e.initCoreError(func, file, line, err);
 
287
                e.log(NULL, "*** Uncaught error");
 
288
        }
 
289
}
 
290
 
 
291
void CSException::throwCoreError(const char *func, const char *file, int line, int err, const char *item)
 
292
{
 
293
        CSThread *self;
 
294
 
 
295
        if ((self = CSThread::getSelf())) {
 
296
                self->myException.initCoreError(func, file, line, err, item);
 
297
                self->myException.setStackTrace(self);
 
298
                self->throwException();
 
299
        }
 
300
        else {
 
301
                CSException e;
 
302
                
 
303
                e.initCoreError(func, file, line, err, item);
 
304
                e.log(NULL, "*** Uncaught error");
 
305
        }
 
306
}
 
307
 
 
308
void CSException::throwOSError(const char *func, const char *file, int line, int err)
 
309
{
 
310
        CSThread *self;
 
311
 
 
312
        if ((self = CSThread::getSelf())) {
 
313
                /* A pending signal has priority over a system error,
 
314
                 * In fact, the pending signal may be the reason for
 
315
                 * system error:
 
316
                 */
 
317
                self->interrupted();
 
318
                self->myException.initOSError(func, file, line, err);
 
319
                self->myException.setStackTrace(self);
 
320
                self->throwException();
 
321
        }
 
322
        else {
 
323
                CSException e;
 
324
                
 
325
                e.initOSError(func, file, line, err);
 
326
                e.log(NULL, "*** Uncaught error");
 
327
        }
 
328
}
 
329
 
 
330
void CSException::throwFileError(const char *func, const char *file, int line, const char *path, int err)
 
331
{
 
332
        CSThread *self;
 
333
 
 
334
        if ((self = CSThread::getSelf())) {
 
335
                self->interrupted();
 
336
                self->myException.initFileError(func, file, line, path, err);
 
337
                self->myException.setStackTrace(self);
 
338
                self->throwException();
 
339
        }
 
340
        else {
 
341
                CSException e;
 
342
                
 
343
                e.initFileError(func, file, line, path, err);
 
344
                e.log(NULL, "*** Uncaught error");
 
345
        }
 
346
}
 
347
 
 
348
void CSException::throwFileError(const char *func, const char *file, int line, CSString *path, int err)
 
349
{
 
350
        CSThread *self;
 
351
 
 
352
        if ((self = CSThread::getSelf())) {
 
353
                self->interrupted();
 
354
                self->myException.initFileError(func, file, line, path->getCString(), err);
 
355
                self->myException.setStackTrace(self);
 
356
                self->throwException();
 
357
        }
 
358
        else {
 
359
                CSException e;
 
360
                
 
361
                e.initFileError(func, file, line, path->getCString(), err);
 
362
                e.log(NULL, "*** Uncaught error");
 
363
        }
 
364
}
 
365
 
 
366
void CSException::throwSignal(const char *func, const char *file, int line, int sig)
 
367
{
 
368
        CSThread *self;
 
369
 
 
370
        if ((self = CSThread::getSelf())) {
 
371
                self->myException.initSignal(func, file, line, sig);
 
372
                self->myException.setStackTrace(self);
 
373
                self->throwException();
 
374
        }
 
375
        else {
 
376
                CSException e;
 
377
                
 
378
                e.initSignal(func, file, line, sig);
 
379
                e.log(NULL, "*** Uncaught error");
 
380
        }
 
381
}
 
382
 
 
383
void CSException::throwEOFError(const char *func, const char *file, int line, const char *path)
 
384
{
 
385
        CSThread *self;
 
386
 
 
387
        if ((self = CSThread::getSelf())) {
 
388
                self->interrupted();
 
389
                self->myException.initEOFError(func, file, line, path);
 
390
                self->myException.setStackTrace(self);
 
391
                self->throwException();
 
392
        }
 
393
        else {
 
394
                CSException e;
 
395
                
 
396
                e.initEOFError(func, file, line, path);
 
397
                e.log(NULL, "*** Uncaught error");
 
398
        }
 
399
}
 
400
 
 
401
void CSException::throwLastError(const char *func, const char *file, int line)
 
402
{
 
403
#ifdef OS_WINDOWS
 
404
        throwOSError(func, file, line, (int) getLastError());
 
405
#else
 
406
        throwOSError(func, file, line, (int) errno);
 
407
#endif
 
408
}
 
409
 
 
410
void CSException::logOSError(const char *func, const char *file, int line, int err)
 
411
{
 
412
        CSThread *self;
 
413
 
 
414
        if ((self = CSThread::getSelf())) {
 
415
                self->myException.initOSError(func, file, line, err);
 
416
                self->myException.setStackTrace(self);
 
417
                self->logException();
 
418
        }
 
419
        else {
 
420
                CSException e;
 
421
                
 
422
                e.initOSError(func, file, line, err);
 
423
                e.log(NULL);
 
424
        }
 
425
}
 
426
 
 
427
void CSException::logOSError(CSThread *self, const char *func, const char *file, int line, int err)
 
428
{
 
429
        self->myException.initOSError(func, file, line, err);
 
430
        self->myException.setStackTrace(self);
 
431
        self->logException();
 
432
}
 
433
 
 
434
void CSException::logException(const char *func, const char *file, int line, int err, const char *message)
 
435
{
 
436
        CSThread *self;
 
437
 
 
438
        if ((self = CSThread::getSelf())) {
 
439
                self->myException.initException(func, file, line, err, message);
 
440
                self->logException();
 
441
        }
 
442
        else {
 
443
                CSException e;
 
444
                
 
445
                e.initException(func, file, line, err,message);
 
446
                e.log(NULL);
 
447
        }
 
448
}
 
449
 
 
450