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, const char *function_name, uword line_number,
113 const 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)
148 __clib_export clib_error_t *
149 _clib_error_return (clib_error_t *errors, any code, uword flags,
150 const char *where, const 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", e->what);
214 if ((vec_end (errors) - 1) != e)
215 s = format (s, "\n");
221 __clib_export clib_error_t *
222 _clib_error_report (clib_error_t * errors)
226 u8 *msg = format (0, "%U", format_clib_error, errors);
228 msg = dispatch_message (msg);
231 if (errors->flags & CLIB_ERROR_ABORT)
233 if (errors->flags & CLIB_ERROR_FATAL)
236 clib_error_free (errors);
246 return error_return (0, "x is odd %d", x);
252 return error_return (0, "x is even %d", x);
264 return error_return (e, 0);
268 error_handler (void *arg, char *msg, int msg_len)
270 write (2, msg, msg_len);
274 main (int argc, char *argv[])
278 register_error_handler (error_handler, 0);
289 * fd.io coding-style-patch-verification: ON
292 * eval: (c-set-style "gnu")