blob: e51f938e79764a7452b089f016717a32f4c5a45e [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
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:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
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.
14 */
15/*
16 Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus
17
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:
25
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
28
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.
36*/
37
38#ifndef included_error_h
39#define included_error_h
40
Dave Barachc3799992016-08-15 11:12:27 -040041#include <vppinfra/clib.h> /* for CLIB_LINUX_KERNEL */
Ed Warnickecb9cada2015-12-08 15:45:58 -070042#include <vppinfra/error_bootstrap.h>
43
44#ifdef CLIB_UNIX
45#include <errno.h>
46#endif
47
48#ifdef CLIB_LINUX_KERNEL
49#include <linux/errno.h>
50#endif
51
52#include <stdarg.h>
53#include <vppinfra/vec.h>
54
55/* Callback functions for error reporting. */
Dave Barachc3799992016-08-15 11:12:27 -040056typedef void clib_error_handler_func_t (void *arg, u8 * msg, int msg_len);
57void clib_error_register_handler (clib_error_handler_func_t func, void *arg);
Ed Warnickecb9cada2015-12-08 15:45:58 -070058
59#define clib_warning(format,args...) \
60 _clib_error (CLIB_ERROR_WARNING, clib_error_function, __LINE__, format, ## args)
61
62#define clib_error(format,args...) \
63 _clib_error (CLIB_ERROR_FATAL, clib_error_function, __LINE__, format, ## args)
64
65#define clib_unix_error(format,args...) \
66 _clib_error (CLIB_ERROR_FATAL | CLIB_ERROR_ERRNO_VALID, clib_error_function, __LINE__, format, ## args)
67
68#define clib_unix_warning(format,args...) \
69 _clib_error (CLIB_ERROR_WARNING | CLIB_ERROR_ERRNO_VALID, clib_error_function, __LINE__, format, ## args)
70
71/* For programming errors and assert. */
72#define clib_panic(format,args...) \
73 _clib_error (CLIB_ERROR_ABORT, (char *) clib_error_function, __LINE__, format, ## args)
74
Dave Barachc3799992016-08-15 11:12:27 -040075typedef struct
76{
Ed Warnickecb9cada2015-12-08 15:45:58 -070077 /* Error message. */
Dave Barachc3799992016-08-15 11:12:27 -040078 u8 *what;
Ed Warnickecb9cada2015-12-08 15:45:58 -070079
80 /* Where error occurred (e.g. __FUNCTION__ __LINE__) */
Dave Barachc3799992016-08-15 11:12:27 -040081 const u8 *where;
Ed Warnickecb9cada2015-12-08 15:45:58 -070082
83 uword flags;
84
85 /* Error code (e.g. errno for Unix errors). */
86 any code;
87} clib_error_t;
88
89#define clib_error_get_code(err) ((err) ? (err)->code : 0)
90#define clib_error_set_code(err, c) \
91do { \
92 if (err) \
93 (err)->code = (c); \
94} while (0)
95
Dave Barachc3799992016-08-15 11:12:27 -040096extern void *clib_error_free_vector (clib_error_t * errors);
Ed Warnickecb9cada2015-12-08 15:45:58 -070097
98#define clib_error_free(e) e = clib_error_free_vector(e)
99
Dave Barachc3799992016-08-15 11:12:27 -0400100extern clib_error_t *_clib_error_return (clib_error_t * errors,
101 any code,
102 uword flags,
103 char *where, char *fmt, ...);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700104
105#define clib_error_return_code(e,code,flags,args...) \
106 _clib_error_return((e),(code),(flags),(char *)clib_error_function,args)
107
108#define clib_error_create(args...) \
109 clib_error_return_code(0,0,0,args)
110
111#define clib_error_return(e,args...) \
112 clib_error_return_code(e,0,0,args)
113
114#define clib_error_return_unix(e,args...) \
115 clib_error_return_code(e,errno,CLIB_ERROR_ERRNO_VALID,args)
116
117#define clib_error_return_fatal(e,args...) \
118 clib_error_return_code(e,0,CLIB_ERROR_FATAL,args)
119
120#define clib_error_return_unix_fatal(e,args...) \
121 clib_error_return_code(e,errno,CLIB_ERROR_ERRNO_VALID|CLIB_ERROR_FATAL,args)
122
Dave Barachc3799992016-08-15 11:12:27 -0400123extern clib_error_t *_clib_error_report (clib_error_t * errors);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700124
125#define clib_error_report(e) do { (e) = _clib_error_report (e); } while (0)
126
Dave Barachc3799992016-08-15 11:12:27 -0400127u8 *format_clib_error (u8 * s, va_list * va);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700128
Dave Barachc3799992016-08-15 11:12:27 -0400129always_inline word
130unix_error_is_fatal (word error)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700131{
132#ifdef CLIB_UNIX
133 switch (error)
134 {
135 case EWOULDBLOCK:
136 case EINTR:
137 return 0;
138 }
139#endif
140 return 1;
141}
142
143#define IF_ERROR_IS_FATAL_RETURN_ELSE_FREE(e) \
144do { \
145 if (e) \
146 { \
147 if (unix_error_is_fatal (clib_error_get_code (e))) \
148 return (e); \
149 else \
150 clib_error_free (e); \
151 } \
152} while (0)
153
154#define ERROR_RETURN_IF(x) \
155do { \
156 clib_error_t * _error_return_if = (x); \
157 if (_error_return_if) \
158 return clib_error_return (_error_return_if, 0); \
159} while (0)
160
161#define ERROR_ASSERT(truth) \
162({ \
163 clib_error_t * _error_assert = 0; \
164 if (CLIB_DEBUG > 0 && ! (truth)) \
165 { \
166 _error_assert = clib_error_return_fatal \
167 (0, "%s:%d (%s) assertion `%s' fails", \
168 __FILE__, \
169 (uword) __LINE__, \
170 clib_error_function, \
171 # truth); \
172 } \
173 _error_assert; \
174})
175
176/* Assert to remain even if CLIB_DEBUG is set to 0. */
177#define CLIB_ERROR_ASSERT(truth) \
178({ \
179 clib_error_t * _error_assert = 0; \
180 if (! (truth)) \
181 { \
182 _error_assert = \
183 clib_error_return_fatal \
184 (0, "%s:%d (%s) assertion `%s' fails", \
185 __FILE__, \
186 (uword) __LINE__, \
187 clib_error_function, \
188 # truth); \
189 } \
190 _error_assert; \
191})
192
Dave Barach3ad77042017-01-04 17:24:32 -0500193/*
194 * If we're running under Coverity, don't die on
195 * failed static assertions.
196 */
197#ifdef __COVERITY__
198#ifndef _Static_assert
199#define _Static_assert(x,y)
200#endif
201#endif
202
Ed Warnickecb9cada2015-12-08 15:45:58 -0700203#endif /* included_error_h */
Dave Barachc3799992016-08-15 11:12:27 -0400204
205/*
206 * fd.io coding-style-patch-verification: ON
207 *
208 * Local Variables:
209 * eval: (c-set-style "gnu")
210 * End:
211 */