2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
18 Permission is hereby granted, free of charge, to any person obtaining
19 a copy of this software and associated documentation files (the
20 "Software"), to deal in the Software without restriction, including
21 without limitation the rights to use, copy, modify, merge, publish,
22 distribute, sublicense, and/or sell copies of the Software, and to
23 permit persons to whom the Software is furnished to do so, subject to
24 the following conditions:
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 /* Error reporting. */
41 #include <vppinfra/clib.h> /* for HAVE_ERRNO */
43 #ifdef CLIB_LINUX_KERNEL
44 #include <linux/unistd.h> /* for write */
45 #include <linux/kernel.h> /* for printk */
49 #include <unistd.h> /* for write */
50 #include <stdio.h> /* for printf */
54 #ifdef CLIB_STANDALONE
55 #include <vppinfra/standalone_stdio.h> /* for printf */
58 #include <vppinfra/string.h>
59 #include <vppinfra/mem.h>
60 #include <vppinfra/vec.h>
61 #include <vppinfra/format.h>
62 #include <vppinfra/error.h>
63 #include <vppinfra/hash.h>
64 #include <vppinfra/os.h> /* for os_panic/os_exit/os_puts */
68 clib_error_handler_func_t *func;
70 } clib_error_handler_t;
72 static clib_error_handler_t *handlers = 0;
75 clib_error_register_handler (clib_error_handler_func_t func, void *arg)
77 clib_error_handler_t h = {.func = func,.arg = arg, };
78 vec_add1 (handlers, h);
94 dispatch_message (u8 * msg)
101 for (i = 0; i < vec_len (handlers); i++)
102 handlers[i].func (handlers[i].arg, msg, vec_len (msg));
104 /* If no message handler is specified provide a default one. */
105 if (vec_len (handlers) == 0)
106 os_puts (msg, vec_len (msg), /* is_error */ 1);
112 _clib_error (int how_to_die,
113 char *function_name, uword line_number, char *fmt, ...)
120 msg = format (msg, "%s:", function_name);
122 msg = format (msg, "%wd:", line_number);
123 msg = format (msg, " ");
127 msg = va_format (msg, fmt, &va);
131 if (how_to_die & CLIB_ERROR_ERRNO_VALID)
132 msg = format (msg, ": %s (errno %d)", strerror (errno), errno);
135 if (vec_end (msg)[-1] != '\n')
136 vec_add1 (msg, '\n');
138 msg = dispatch_message (msg);
142 if (how_to_die & CLIB_ERROR_ABORT)
144 if (how_to_die & CLIB_ERROR_FATAL)
149 _clib_error_return (clib_error_t * errors,
150 any code, uword flags, char *where, char *fmt, ...)
156 /* Save errno since it may be re-set before we'll need it. */
157 word errno_save = errno;
161 vec_add2 (errors, e, 1);
163 e->what = va_format (0, fmt, &va);
166 if (flags & CLIB_ERROR_ERRNO_VALID)
169 e->what = format (e->what, ": ");
170 e->what = format (e->what, "%s", strerror (errno_save));
174 e->where = (u8 *) where;
182 clib_error_free_vector (clib_error_t * errors)
185 vec_foreach (e, errors) vec_free (e->what);
191 format_clib_error (u8 * s, va_list * va)
193 clib_error_t *errors = va_arg (*va, clib_error_t *);
196 vec_foreach (e, errors)
206 where = format (where, "from ");
207 where = format (where, "%s", e->where);
209 s = format (s, "%v: ", where);
213 s = format (s, "%v\n", e->what);
220 _clib_error_report (clib_error_t * errors)
224 u8 *msg = format (0, "%U", format_clib_error, errors);
226 msg = dispatch_message (msg);
229 if (errors->flags & CLIB_ERROR_ABORT)
231 if (errors->flags & CLIB_ERROR_FATAL)
234 clib_error_free (errors);
244 return error_return (0, "x is odd %d", x);
250 return error_return (0, "x is even %d", x);
262 return error_return (e, 0);
266 error_handler (void *arg, char *msg, int msg_len)
268 write (2, msg, msg_len);
272 main (int argc, char *argv[])
276 register_error_handler (error_handler, 0);
287 * fd.io coding-style-patch-verification: ON
290 * eval: (c-set-style "gnu")