1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
7  *
8  * See the COPYRIGHT file distributed with this work for additional
9  * information regarding copyright ownership.
10  */
11 
12 /*! \file */
13 
14 #include <stdio.h>
15 #include <stdlib.h>
16 
17 #include <isc/error.h>
18 #include <isc/print.h>
19 
20 /*% Default unexpected callback. */
21 static void
22 default_unexpected_callback(const char *, int, const char *, va_list)
23 	ISC_FORMAT_PRINTF(3, 0);
24 
25 /*% Default fatal callback. */
26 static void
27 default_fatal_callback(const char *, int, const char *, va_list)
28 	ISC_FORMAT_PRINTF(3, 0);
29 
30 /*% unexpected_callback */
31 static isc_errorcallback_t unexpected_callback = default_unexpected_callback;
32 static isc_errorcallback_t fatal_callback = default_fatal_callback;
33 
34 void
isc_error_setunexpected(isc_errorcallback_t cb)35 isc_error_setunexpected(isc_errorcallback_t cb) {
36 	if (cb == NULL) {
37 		unexpected_callback = default_unexpected_callback;
38 	} else {
39 		unexpected_callback = cb;
40 	}
41 }
42 
43 void
isc_error_setfatal(isc_errorcallback_t cb)44 isc_error_setfatal(isc_errorcallback_t cb) {
45 	if (cb == NULL) {
46 		fatal_callback = default_fatal_callback;
47 	} else {
48 		fatal_callback = cb;
49 	}
50 }
51 
52 void
isc_error_unexpected(const char * file,int line,const char * format,...)53 isc_error_unexpected(const char *file, int line, const char *format, ...) {
54 	va_list args;
55 
56 	va_start(args, format);
57 	(unexpected_callback)(file, line, format, args);
58 	va_end(args);
59 }
60 
61 void
isc_error_fatal(const char * file,int line,const char * format,...)62 isc_error_fatal(const char *file, int line, const char *format, ...) {
63 	va_list args;
64 
65 	va_start(args, format);
66 	(fatal_callback)(file, line, format, args);
67 	va_end(args);
68 	abort();
69 }
70 
71 void
isc_error_runtimecheck(const char * file,int line,const char * expression)72 isc_error_runtimecheck(const char *file, int line, const char *expression) {
73 	isc_error_fatal(file, line, "RUNTIME_CHECK(%s) failed", expression);
74 }
75 
76 static void
default_unexpected_callback(const char * file,int line,const char * format,va_list args)77 default_unexpected_callback(const char *file, int line, const char *format,
78 			    va_list args) {
79 	fprintf(stderr, "%s:%d: ", file, line);
80 	vfprintf(stderr, format, args);
81 	fprintf(stderr, "\n");
82 	fflush(stderr);
83 }
84 
85 static void
default_fatal_callback(const char * file,int line,const char * format,va_list args)86 default_fatal_callback(const char *file, int line, const char *format,
87 		       va_list args) {
88 	fprintf(stderr, "%s:%d: fatal error: ", file, line);
89 	vfprintf(stderr, format, args);
90 	fprintf(stderr, "\n");
91 	fflush(stderr);
92 }
93