~drizzle-trunk/drizzle/development

1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
1
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
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
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
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
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
30
#ifdef OS_WINDOWS
31
#define strsignal(s) NULL
32
#else
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
33
#include <sys/signal.h>
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
34
#endif
35
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
36
#include <limits.h>
37
#include <string.h>
38
39
#include "CSGlobal.h"
40
#include "CSException.h"
41
#include "CSStrUtil.h"
42
#include "CSLog.h"
43
44
void CSException::setStackTrace(CSThread *self, const char *stack)
45
{
46
	char buffer[CS_EXC_CONTEXT_SIZE];
47
48
	self->myException.iStackTrace.setLength(0);
49
	if (stack)
50
		self->myException.iStackTrace.append(stack);
51
	for (int i=self->callTop-1; i>=0; i--) {
52
		cs_format_context(CS_EXC_CONTEXT_SIZE, buffer,
53
			self->callStack[i].cs_func, self->callStack[i].cs_file, self->callStack[i].cs_line);
54
		self->myException.iStackTrace.append(buffer);
55
		self->myException.iStackTrace.append('\n');
56
	}
57
}
58
59
void CSException::setStackTrace(CSThread *self)
60
{
61
	setStackTrace(self, NULL);
62
}
63
64
const char *CSException::getStackTrace()
65
{
66
	return iStackTrace.getCString();
67
}
68
69
void CSException::log(CSThread *self)
70
{
71
	CSL.lock();
72
	CSL.log(self, CSLog::Error, getContext());
73
	CSL.log(self, CSLog::Error, " ");
74
	CSL.log(self, CSLog::Error, getMessage());
75
	CSL.eol(self, CSLog::Error);
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
76
#ifdef DUMP_STACK_TRACE
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
77
	CSL.log(self, CSLog::Error, getStackTrace());
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
78
#endif
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
79
	CSL.unlock();
80
}
81
82
void CSException::log(CSThread *self, const char *message)
83
{
84
	CSL.lock();
85
	CSL.log(self, CSLog::Error, message);
86
	CSL.eol(self, CSLog::Error);
87
	CSL.log(self, CSLog::Error, getContext());
88
	CSL.log(self, CSLog::Error, " ");
89
	CSL.log(self, CSLog::Error, getMessage());
90
	CSL.eol(self, CSLog::Error);
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
91
#ifdef DUMP_STACK_TRACE
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
92
	CSL.log(self, CSLog::Error, getStackTrace());
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
93
#endif
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
94
	CSL.unlock();
95
}
96
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
97
void CSException::initException_va(const char *func, const char *file, int line, int err, const char *fmt, va_list ap)
98
{
99
100
	cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
101
	iErrorCode = err;
102
#ifdef OS_WINDOWS
103
	vsprintf(iMessage, fmt, ap);
104
#else
105
	size_t len;
106
	len = vsnprintf(iMessage, CS_EXC_MESSAGE_SIZE-1, fmt, ap);
107
	if (len > CS_EXC_MESSAGE_SIZE-1)
108
		len = CS_EXC_MESSAGE_SIZE-1;
109
	iMessage[len] = 0;
110
#endif
111
}
112
113
void CSException::initExceptionf(const char *func, const char *file, int line, int err, const char *fmt, ...)
114
{
115
	va_list ap;
116
117
	va_start(ap, fmt);
118
	initException_va(func, file, line, err, fmt, ap);
119
	va_end(ap);
120
}
121
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
122
void CSException::initException(const char *func, const char *file, int line, int err, const char *message)
123
{
124
	cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
125
	iErrorCode = err;
126
	cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, message);
127
}
128
1548.2.11 by Barry.Leslie at PrimeBase
Removed libxml reqirement by using a home grown xml parser.
129
void CSException::initException(CSException &exception)
130
{
131
	iErrorCode = exception.iErrorCode;
132
	strcpy(iContext, exception.iContext);
133
	strcpy(iMessage, exception.iMessage);
134
	
135
	iStackTrace.setLength(0);
136
	iStackTrace.append(exception.iStackTrace.getCString());
137
138
}
139
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
140
void CSException::initAssertion(const char *func, const char *file, int line, const char *message)
141
{
142
	cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
143
	iErrorCode = CS_ERR_ASSERTION;
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
144
	cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "Assertion failed: ");
145
	cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, message);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
146
}
147
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
148
void CSException::getCoreError(uint32_t size, char *buffer, int err)
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
149
{
150
	const char *message = NULL;
151
152
	switch (err) {
153
		case CS_ERR_JUMP_OVERFLOW: message = "Jump stack overflow"; break;
154
		case CS_ERR_BAD_ADDRESS: message = "Incorrect network address: %"; break;
155
		case CS_ERR_UNKNOWN_SERVICE: message = "Unknown network service: %"; break;
156
		case CS_ERR_UNKNOWN_HOST:  message = "Unknown host: %"; break;
157
		case CS_ERR_UNKNOWN_METHOD: message = "Unknown HTTP method: %"; break;
158
		case CS_ERR_NO_LISTENER: message = "Listening port has been closed"; break;
159
		case CS_ERR_RELEASE_OVERFLOW: message = "Release stack overflow"; break;
160
		case CS_ERR_IMPL_MISSING: message = "Function %s not implemented"; break;
161
		case CS_ERR_BAD_HEADER_MAGIC: message = "Incorrect file type"; break;
162
		case CS_ERR_VERSION_TOO_NEW: message = "Incompatible file version"; break;
163
	}
164
	if (message)
165
		cs_strcpy(size, buffer, message);
166
	else {
167
		cs_strcpy(size, buffer, "Unknown system error ");
168
		cs_strcat(size, buffer, err);
169
	}
170
}
171
172
void CSException::initCoreError(const char *func, const char *file, int line, int err)
173
{
174
	cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
175
	iErrorCode = err;
176
	getCoreError(CS_EXC_MESSAGE_SIZE, iMessage, err);
177
}
178
179
void CSException::initCoreError(const char *func, const char *file, int line, int err, const char *item)
180
{
181
	cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
182
	iErrorCode = err;
183
	getCoreError(CS_EXC_MESSAGE_SIZE, iMessage, err);
1841.1.6 by Barry.Leslie at PrimeBase
Updating PBMS code to match pbms revision 244
184
	cs_replace_string(CS_EXC_MESSAGE_SIZE, iMessage, "%s", item);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
185
}
186
187
void CSException::initOSError(const char *func, const char *file, int line, int err)
188
{
189
	char *msg;
190
191
	cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
192
	iErrorCode = err;
193
194
#ifdef XT_WIN
195
	if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, iMessage, CS_EXC_MESSAGE_SIZE, NULL)) {
196
		char *ptr;
197
198
		ptr = &iMessage[strlen(iMessage)];
199
		while (ptr-1 > err_msg) {
200
			if (*(ptr-1) != '\n' && *(ptr-1) != '\r' && *(ptr-1) != '.')
201
				break;
202
			ptr--;
203
		}
204
		*ptr = 0;
205
206
		cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, " (");
207
		cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, err);
208
		cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ")");
209
		return;
210
	}
211
#endif
212
213
	msg = strerror(err);
214
	if (msg) {
215
		cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, msg);
216
		cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, " (");
217
		cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, err);
218
		cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ")");
219
	}
220
	else {
221
		cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "Unknown OS error code ");
222
		cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, err);
223
	}
224
}
225
226
void CSException::initFileError(const char *func, const char *file, int line, const char *path, int err)
227
{
228
	initOSError(func, file, line, err);
229
	cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ": '");
230
	cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, path);
231
	cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, "'");
232
}
233
234
void CSException::initSignal(const char *func, const char *file, int line, int sig)
235
{
236
	char *str;
237
238
	cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
239
	iErrorCode = sig;
240
	if (!(str = strsignal(sig))) {
241
		cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "Unknown signal ");
242
		cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, sig);
243
	}
244
	else {
245
		cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, str);
246
		cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, " (");
247
		cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, sig);
248
		cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, ")");
249
	}
250
}
251
252
void CSException::initEOFError(const char *func, const char *file, int line, const char *path)
253
{
254
	cs_format_context(CS_EXC_CONTEXT_SIZE, iContext, func, file, line);
255
	iErrorCode = CS_ERR_EOF;
256
	cs_strcpy(CS_EXC_MESSAGE_SIZE, iMessage, "EOF encountered: '");
257
	cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, path);
258
	cs_strcat(CS_EXC_MESSAGE_SIZE, iMessage, "'");
259
}
260
261
void CSException::RecordException(const char *func, const char *file, int line, int err, const char *message)
262
{
263
	CSThread *self;
264
265
	if ((self = CSThread::getSelf())) {
266
		if (!self->myException.getErrorCode())
267
			self->myException.initException(func, file, line, err, message);
268
	}
269
}
270
271
void CSException::ClearException()
272
{
273
	CSThread *self;
274
275
	if ((self = CSThread::getSelf())) {
276
		self->myException.setErrorCode(0);
277
	}
278
}
279
280
void CSException::throwException(const char *func, const char *file, int line, int err, const char *message, const char *stack)
281
{
282
	CSThread *self;
283
284
	if ((self = CSThread::getSelf())) {
285
		self->myException.initException(func, file, line, err, message);
286
		self->myException.setStackTrace(self, stack);
287
		self->throwException();
288
	}
289
	else {
290
		CSException e;
291
		
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
292
		e.initException(func, file, line, err, message);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
293
		e.log(NULL, "*** Uncaught error");
294
	}
295
}
296
297
void CSException::throwException(const char *func, const char *file, int line, int err, const char *message)
298
{
299
	throwException(func, file, line, err, message, NULL);
300
}
301
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
302
void CSException::throwExceptionf(const char *func, const char *file, int line, int err, const char *fmt, ...)
303
{
304
	CSThread	*self;
305
	va_list		ap;
306
307
	va_start(ap, fmt);
308
	if ((self = CSThread::getSelf())) {
309
		self->myException.initException_va(func, file, line, err, fmt, ap);
310
		va_end(ap);
311
		self->myException.setStackTrace(self, NULL);
312
		self->throwException();
313
	}
314
	else {
315
		CSException e;
316
		
317
		e.initException_va(func, file, line, err, fmt, ap);
318
		va_end(ap);
319
		e.log(NULL, "*** Uncaught error");
320
	}
321
}
322
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
323
void CSException::throwAssertion(const char *func, const char *file, int line, const char *message)
324
{
325
	CSThread *self;
326
327
	if ((self = CSThread::getSelf())) {
328
		self->myException.initAssertion(func, file, line, message);
329
		self->myException.setStackTrace(self);
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
330
		/* Not sure why we log the excpetion down here?!
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
331
		self->logException();
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
332
		*/
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
333
		self->throwException();
334
	}
335
	else {
336
		CSException e;
337
		
338
		e.initAssertion(func, file, line, message);
339
		e.log(NULL, "*** Uncaught error");
340
	}
341
}
342
343
void CSException::throwCoreError(const char *func, const char *file, int line, int err)
344
{
345
	CSThread *self;
346
347
	if ((self = CSThread::getSelf())) {
348
		self->myException.initCoreError(func, file, line, err);
349
		self->myException.setStackTrace(self);
350
		self->throwException();
351
	}
352
	else {
353
		CSException e;
354
		
355
		e.initCoreError(func, file, line, err);
356
		e.log(NULL, "*** Uncaught error");
357
	}
358
}
359
360
void CSException::throwCoreError(const char *func, const char *file, int line, int err, const char *item)
361
{
362
	CSThread *self;
363
364
	if ((self = CSThread::getSelf())) {
365
		self->myException.initCoreError(func, file, line, err, item);
366
		self->myException.setStackTrace(self);
367
		self->throwException();
368
	}
369
	else {
370
		CSException e;
371
		
372
		e.initCoreError(func, file, line, err, item);
373
		e.log(NULL, "*** Uncaught error");
374
	}
375
}
376
377
void CSException::throwOSError(const char *func, const char *file, int line, int err)
378
{
379
	CSThread *self;
380
381
	if ((self = CSThread::getSelf())) {
382
		/* A pending signal has priority over a system error,
383
		 * In fact, the pending signal may be the reason for
384
		 * system error:
385
		 */
386
		self->interrupted();
387
		self->myException.initOSError(func, file, line, err);
388
		self->myException.setStackTrace(self);
389
		self->throwException();
390
	}
391
	else {
392
		CSException e;
393
		
394
		e.initOSError(func, file, line, err);
395
		e.log(NULL, "*** Uncaught error");
396
	}
397
}
398
399
void CSException::throwFileError(const char *func, const char *file, int line, const char *path, int err)
400
{
401
	CSThread *self;
402
403
	if ((self = CSThread::getSelf())) {
404
		self->interrupted();
405
		self->myException.initFileError(func, file, line, path, err);
406
		self->myException.setStackTrace(self);
407
		self->throwException();
408
	}
409
	else {
410
		CSException e;
411
		
412
		e.initFileError(func, file, line, path, err);
413
		e.log(NULL, "*** Uncaught error");
414
	}
415
}
416
417
void CSException::throwFileError(const char *func, const char *file, int line, CSString *path, int err)
418
{
419
	CSThread *self;
420
421
	if ((self = CSThread::getSelf())) {
422
		self->interrupted();
423
		self->myException.initFileError(func, file, line, path->getCString(), err);
424
		self->myException.setStackTrace(self);
425
		self->throwException();
426
	}
427
	else {
428
		CSException e;
429
		
430
		e.initFileError(func, file, line, path->getCString(), err);
431
		e.log(NULL, "*** Uncaught error");
432
	}
433
}
434
435
void CSException::throwSignal(const char *func, const char *file, int line, int sig)
436
{
437
	CSThread *self;
438
439
	if ((self = CSThread::getSelf())) {
440
		self->myException.initSignal(func, file, line, sig);
441
		self->myException.setStackTrace(self);
442
		self->throwException();
443
	}
444
	else {
445
		CSException e;
446
		
447
		e.initSignal(func, file, line, sig);
448
		e.log(NULL, "*** Uncaught error");
449
	}
450
}
451
452
void CSException::throwEOFError(const char *func, const char *file, int line, const char *path)
453
{
454
	CSThread *self;
455
456
	if ((self = CSThread::getSelf())) {
457
		self->interrupted();
458
		self->myException.initEOFError(func, file, line, path);
459
		self->myException.setStackTrace(self);
460
		self->throwException();
461
	}
462
	else {
463
		CSException e;
464
		
465
		e.initEOFError(func, file, line, path);
466
		e.log(NULL, "*** Uncaught error");
467
	}
468
}
469
470
void CSException::throwLastError(const char *func, const char *file, int line)
471
{
472
#ifdef OS_WINDOWS
1841.1.3 by Barry.Leslie at PrimeBase
Merged changes from lp:pbms. These changes should remove any danger
473
	throwOSError(func, file, line, (int) GetLastError());
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
474
#else
475
	throwOSError(func, file, line, (int) errno);
476
#endif
477
}
478
479
void CSException::logOSError(const char *func, const char *file, int line, int err)
480
{
481
	CSThread *self;
482
483
	if ((self = CSThread::getSelf())) {
484
		self->myException.initOSError(func, file, line, err);
485
		self->myException.setStackTrace(self);
486
		self->logException();
487
	}
488
	else {
489
		CSException e;
490
		
491
		e.initOSError(func, file, line, err);
492
		e.log(NULL);
493
	}
494
}
495
496
void CSException::logOSError(CSThread *self, const char *func, const char *file, int line, int err)
497
{
498
	self->myException.initOSError(func, file, line, err);
499
	self->myException.setStackTrace(self);
500
	self->logException();
501
}
502
503
void CSException::logException(const char *func, const char *file, int line, int err, const char *message)
504
{
505
	CSThread *self;
506
507
	if ((self = CSThread::getSelf())) {
508
		self->myException.initException(func, file, line, err, message);
509
		self->logException();
510
	}
511
	else {
512
		CSException e;
513
		
514
		e.initException(func, file, line, err,message);
515
		e.log(NULL);
516
	}
517
}
518
519