The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
strerror.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16 */
17
18/** Support functions to allow libraries to provide errors to their callers
19 *
20 * @file src/lib/util/strerror.h
21 *
22 * @copyright 2017-2020 The FreeRADIUS server project
23 * @copyright 2017-2020 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24 */
25RCSIDH(strerror_h, "$Id: afd4f63b86929d168e75a856ce630790ddc8d2a5 $")
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#include <freeradius-devel/build.h>
32#include <freeradius-devel/missing.h>
33#include <string.h>
34#include <stdarg.h>
35
36/** @name Add an error string to the thread local error stack
37 *
38 * @note printf functions should not be used in decoder libraries as an
39 * attacker may be able to exploit them to consume excessive amounts
40 * of CPU time. Use fr_strerror_const_* functions instead.
41 *
42 * @{
43 */
44#define fr_strerror_vprintf(_fmt, _ap) _fr_strerror_vprintf(__FILE__, __LINE__, _fmt, _ap)
45/** @hidecallergraph */
46void _fr_strerror_vprintf(char const *file, int line, char const *fmt, va_list ap);
47
48#define fr_strerror_vprintf_push(_fmt, _ap) _fr_strerror_vprintf_push(__FILE__, __LINE, _fmt, _ap)
49/** @hidecallergraph */
50void _fr_strerror_vprintf_push(char const *file, int line, char const *fmt, va_list ap);
51
52#define fr_strerror_vprintf_push_head(_fmt, _ap) _fr_strerror_vprintf_push_head(__FILE__, __LINE__, _fmt, _ap)
53/** @hidecallergraph */
54void _fr_strerror_vprintf_push_head(char const *file, int line, char const *fmt, va_list ap);
55
56/** Log to thread local error buffer
57 *
58 * @param[in] _fmt printf style format string.
59 * If NULL clears any existing messages.
60 * @param[in] ... Arguments for the format string.
61 *
62 * @hidecallergraph
63 */
64#define fr_strerror_printf(_fmt, ...) \
65 _fr_strerror_printf(__FILE__, __LINE__, _fmt, ##__VA_ARGS__)
66
67static inline CC_HINT(nonnull) CC_HINT(format (printf, 3, 4))
68void _fr_strerror_printf(char const *file, int line, char const *fmt, ...)
69{
70 va_list ap;
71
72 va_start(ap, fmt);
74 va_end(ap);
75}
76
77/** Add a message to an existing stack of messages at the tail
78 *
79 * @param[in] _fmt printf style format string.
80 * @param[in] ... Arguments for the format string.
81 *
82 * @hidecallergraph
83 */
84#define fr_strerror_printf_push(_fmt, ...) \
85 _fr_strerror_printf_push(__FILE__, __LINE__, _fmt, ##__VA_ARGS__)
86
87static inline CC_HINT(nonnull) CC_HINT(format (printf, 3, 4))
88void _fr_strerror_printf_push(char const *file, int line, char const *fmt, ...)
89{
90 va_list ap;
91
92 va_start(ap, fmt);
94 va_end(ap);
95}
96
97/** Add a message to an existing stack of messages at the head
98 *
99 * @param[in] _fmt printf style format string.
100 * @param[in] ... Arguments for the format string.
101 *
102 * @hidecallergraph
103 */
104#define fr_strerror_printf_push_head(_fmt, ...) \
105 _fr_strerror_printf_push_head(__FILE__, __LINE__, _fmt, ##__VA_ARGS__)
106
107static inline CC_HINT(nonnull) CC_HINT(format (printf, 3, 4))
108void _fr_strerror_printf_push_head(char const *file, int line, char const *fmt, ...)
109{
110 va_list ap;
111
112 va_start(ap, fmt);
114 va_end(ap);
115}
116/** @} */
117
118/** @name Add an error string with marker to the thread local error stack
119 *
120 * @note printf functions should not be used in decoder libraries as an
121 * attacker may be able to exploit them to consume excessive amounts
122 * of CPU time. Use fr_strerror_const_* functions instead.
123 *
124 * @{
125 */
126#define fr_strerror_marker_vprintf(_subject, _offset, _fmt, _ap) \
127 _fr_strerror_marker_vprintf(__FILE__, __LINE__, _subject, _offset, _fmt, _ap)
128/** @hidecallergraph */
129void _fr_strerror_marker_vprintf(char const *file, int line,
130 char const *subject, size_t offset, char const *fmt, va_list ap);
131
132#define fr_strerror_marker_vprintf_push(_subject, _offset, _fmt, _ap) \
133 _fr_strerror_marker_vprintf_push(__FILE__, __LINE__, _subject, _offset, _fmt, _ap)
134/** @hidecallergraph */
135void _fr_strerror_marker_vprintf_push(char const *file, int line,
136 char const *subject, size_t offset, char const *fmt, va_list ap);
137
138#define fr_strerror_marker_vprintf_push_head(_subject, _offset, _fmt, _ap) \
139 _fr_strerror_marker_vprintf_push_head(__FILE__, __LINE__, _subject, _offset, _fmt, _ap)
140/** @hidecallergraph */
142 char const *subject, size_t offset, char const *fmt, va_list ap);
143
144/** Add an error marker to an existing stack of messages
145 *
146 * @param[in] _subject to mark up.
147 * @param[in] _offset Positive offset to show where the error
148 * should be positioned.
149 * @param[in] _fmt Error string.
150 * @param[in] ... Arguments for the error string.
151 *
152 * @hidecallergraph
153 */
154#define fr_strerror_marker_printf(_subject, _offset, _fmt, ...) \
155 _fr_strerror_marker_printf(__FILE__, __LINE__, _subject, _offset, _fmt, ##__VA_ARGS__)
156
157static inline CC_HINT(nonnull) CC_HINT(format (printf, 5, 6))
159 char const *subject, size_t offset, char const *fmt, ...)
160{
161 va_list ap;
162
163 va_start(ap, fmt);
164 _fr_strerror_marker_vprintf(file, line, subject, offset, fmt, ap);
165 va_end(ap);
166}
167
168/** Add an error marker to an existing stack of messages at the tail
169 *
170 * @param[in] _subject to mark up.
171 * @param[in] _offset Positive offset to show where the error
172 * should be positioned.
173 * @param[in] _fmt Error string.
174 * @param[in] ... Arguments for the error string.
175 *
176 * @hidecallergraph
177 */
178#define fr_strerror_marker_printf_push(_subject, _offset, _fmt, ...) \
179 _fr_strerror_marker_printf_push(__FILE__, __LINE__, _subject, _offset, _fmt, ##__VA_ARGS__)
180
181static inline CC_HINT(nonnull) CC_HINT(format (printf, 5, 6))
183 char const *subject, size_t offset, char const *fmt, ...)
184{
185 va_list ap;
186
187 va_start(ap, fmt);
188 _fr_strerror_marker_vprintf_push(file, line, subject, offset, fmt, ap);
189 va_end(ap);
190}
191
192/** Add an error marker to an existing stack of messages at the head
193 *
194 * @param[in] _subject to mark up.
195 * @param[in] _offset Positive offset to show where the error
196 * should be positioned.
197 * @param[in] _fmt Error string.
198 * @param[in] ... Arguments for the error string.
199 *
200 * @hidecallergraph
201 */
202#define fr_strerror_marker_printf_push_head(_subject, _offset, _fmt, ...) \
203 _fr_strerror_marker_printf_push_head(__FILE__, __LINE__, _subject, _offset, _fmt, ##__VA_ARGS__)
204
205static inline CC_HINT(nonnull) CC_HINT(format (printf, 5, 6))
207 char const *subject, size_t offset, char const *fmt, ...)
208{
209 va_list ap;
210
211 va_start(ap, fmt);
212 _fr_strerror_marker_vprintf_push_head(file, line, subject, offset, fmt, ap);
213 va_end(ap);
214}
215/** @} */
216
217/** @name Add a const error string to the thread local error stack
218 *
219 * @note This ~30x the speed of the printf variants, and should be used wherever possible
220 *
221 * @{
222 */
223#define fr_strerror_const(_msg) _fr_strerror_const(__FILE__, __LINE__, _msg)
224/** @hidecallergraph */
225void _fr_strerror_const(char const *file, int line, char const *msg) CC_HINT(nonnull);
226
227#define fr_strerror_const_push(_msg) _fr_strerror_const_push(__FILE__, __LINE__, _msg)
228/** @hidecallergraph */
229void _fr_strerror_const_push(char const *file, int line, char const *msg) CC_HINT(nonnull);
230
231#define fr_strerror_const_push_head(_msg) _fr_strerror_const_push_head(__FILE__, __LINE__, _msg)
232/** @hidecallergraph */
233void _fr_strerror_const_push_head(char const *file, int line, char const *msg) CC_HINT(nonnull);
234/** @} */
235
236/** @name Retrieve errors from the thread local error stack
237 *
238 * @{
239 */
240/** @hidecallergraph */
241char const *fr_strerror(void) CC_HINT(warn_unused_result);
242
243/** @hidecallergraph */
244void fr_strerror_clear(void);
245
246/** @hidecallergraph */
247char const *fr_strerror_marker(char const **subject, size_t *offset) CC_HINT(nonnull);
248
249/** @hidecallergraph */
250char const *fr_strerror_peek(void);
251
252/** @hidecallergraph */
253char const *fr_strerror_marker_peek(char const **subject, size_t *offset) CC_HINT(nonnull);
254
255/** @hidecallergraph */
256char const *fr_strerror_pop(void);
257
258/** @hidecallergraph */
259char const *fr_strerror_marker_pop(char const **subject, size_t *offset) CC_HINT(nonnull);
260
261/** @hidecallergraph */
262void fr_perror(char const *, ...) CC_HINT(format (printf, 1, 2));
263
264/** @hidecallergraph */
265char const *fr_perror_to_str(char const *line_sep, char const *fmt, ...) CC_HINT(format (printf, 2, 3));
266/** @} */
267
268#ifdef __cplusplus
269}
270#endif
int const char * file
Definition acutest.h:702
va_end(args)
log_entry msg
Definition acutest.h:794
static int const char * fmt
Definition acutest.h:573
int const char int line
Definition acutest.h:702
va_start(args, fmt)
#define RCSIDH(h, id)
Definition build.h:484
void _fr_strerror_marker_vprintf_push(char const *file, int line, char const *subject, size_t offset, char const *fmt, va_list ap)
Add an error marker to an existing stack of messages at the tail.
Definition strerror.c:348
static void _fr_strerror_marker_printf(char const *file, int line, char const *subject, size_t offset, char const *fmt,...)
Definition strerror.h:158
void _fr_strerror_const_push(char const *file, int line, char const *msg)
Add a message to an existing stack of messages at the tail.
Definition strerror.c:508
static void _fr_strerror_printf_push_head(char const *file, int line, char const *fmt,...)
Definition strerror.h:108
char const * fr_strerror(void)
Get the last library error.
Definition strerror.c:554
static void _fr_strerror_printf(char const *file, int line, char const *fmt,...)
Definition strerror.h:68
char const * fr_strerror_peek(void)
Get the last library error.
Definition strerror.c:627
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
Definition strerror.c:577
static void _fr_strerror_printf_push(char const *file, int line, char const *fmt,...)
Definition strerror.h:88
static void _fr_strerror_marker_printf_push(char const *file, int line, char const *subject, size_t offset, char const *fmt,...)
Definition strerror.h:182
char const * fr_strerror_marker_pop(char const **subject, size_t *offset)
Pop the last library error with marker information.
Definition strerror.c:708
static void _fr_strerror_marker_printf_push_head(char const *file, int line, char const *subject, size_t offset, char const *fmt,...)
Definition strerror.h:206
void _fr_strerror_const_push_head(char const *file, int line, char const *msg)
Add a message to an existing stack of messages at the head.
Definition strerror.c:531
void fr_perror(char const *,...))
Print the current error to stderr with a prefix.
Definition strerror.c:733
char const * fr_perror_to_str(char const *line_sep, char const *fmt,...))
Print the stack of string buffers to a thread local buffer.
Definition strerror.c:779
void _fr_strerror_vprintf_push(char const *file, int line, char const *fmt, va_list ap)
Add a message to an existing stack of messages at the tail.
Definition strerror.c:263
void _fr_strerror_marker_vprintf(char const *file, int line, char const *subject, size_t offset, char const *fmt, va_list ap)
Add an error marker to an existing stack of messages.
Definition strerror.c:320
void _fr_strerror_vprintf_push_head(char const *file, int line, char const *fmt, va_list ap)
Add a message to an existing stack of messages at the head.
Definition strerror.c:290
void _fr_strerror_const(char const *file, int line, char const *msg)
Log to thread local error buffer.
Definition strerror.c:450
char const * fr_strerror_pop(void)
Pop the last library error.
Definition strerror.c:681
void _fr_strerror_marker_vprintf_push_head(char const *file, int line, char const *subject, size_t offset, char const *fmt, va_list ap)
Add an error marker to an existing stack of messages at the head.
Definition strerror.c:382
char const * fr_strerror_marker_peek(char const **subject, size_t *offset)
Get the last library error marker.
Definition strerror.c:651
char const * fr_strerror_marker(char const **subject, size_t *offset)
Get the last library error marker.
Definition strerror.c:598
void _fr_strerror_vprintf(char const *file, int line, char const *fmt, va_list ap)
Log to thread local error buffer.
Definition strerror.c:245
int nonnull(2, 5))