Imported Upstream version 1.8.7
[debian/sudo] / include / error.h
1 /*
2  * Copyright (c) 2004, 2010-2013 Todd C. Miller <Todd.Miller@courtesan.com>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #ifndef _SUDO_ERROR_H_
18 #define _SUDO_ERROR_H_
19
20 #include <stdarg.h>
21 #include <setjmp.h>
22
23 /*
24  * We wrap fatal/fatalx and warning/warningx so that the same output can
25  * go to the debug file, if there is one.
26  */
27 #if defined(SUDO_ERROR_WRAP) && SUDO_ERROR_WRAP == 0
28 # if defined(__GNUC__) && __GNUC__ == 2
29 #  define fatal(fmt...) fatal_nodebug(fmt)
30 #  define fatalx(fmt...) fatalx_nodebug(fmt)
31 #  define warning(fmt...) warning_nodebug(fmt)
32 #  define warningx(fmt...) warningx_nodebug(fmt)
33 # else
34 #  define fatal(...) fatal_nodebug(__VA_ARGS__)
35 #  define fatalx(...) fatalx_nodebug(__VA_ARGS__)
36 #  define warning(...) warning_nodebug(__VA_ARGS__)
37 #  define warningx(...) warningx_nodebug(__VA_ARGS__)
38 # endif /* __GNUC__ == 2 */
39 # define vfatal(fmt, ap) fatal_nodebug((fmt), (ap))
40 # define vfatalx(fmt, ap) fatalx_nodebug((fmt), (ap))
41 # define vwarning(fmt, ap) warning_nodebug((fmt), (ap))
42 # define vwarningx(fmt, ap) warningx_nodebug((fmt), (ap))
43 #else /* SUDO_ERROR_WRAP */
44 # if defined(__GNUC__) && __GNUC__ == 2
45 #  define fatal(fmt...) do {                                           \
46     sudo_debug_printf2(__func__, __FILE__, __LINE__,                           \
47         SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
48         fmt);                                                                  \
49     fatal_nodebug(fmt);                                                \
50 } while (0)
51 #  define fatalx(fmt...) do {                                          \
52     sudo_debug_printf2(__func__, __FILE__, __LINE__,                           \
53         SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt);            \
54     fatalx_nodebug(fmt);                                               \
55 } while (0)
56 #  define warning(fmt...) do {                                                 \
57     sudo_debug_printf2(__func__, __FILE__, __LINE__,                           \
58         SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
59         fmt);                                                                  \
60     warning_nodebug(fmt);                                                      \
61 } while (0)
62 #  define warningx(fmt...) do {                                                \
63     sudo_debug_printf2(__func__, __FILE__, __LINE__,                           \
64         SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt);            \
65     warningx_nodebug(fmt);                                                     \
66 } while (0)
67 # else
68 #  define fatal(...) do {                                                      \
69     sudo_debug_printf2(__func__, __FILE__, __LINE__,                           \
70         SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
71         __VA_ARGS__);                                                          \
72     fatal_nodebug(__VA_ARGS__);                                        \
73 } while (0)
74 #  define fatalx(...) do {                                             \
75     sudo_debug_printf2(__func__, __FILE__, __LINE__,                           \
76         SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__);    \
77     fatalx_nodebug(__VA_ARGS__);                                       \
78 } while (0)
79 #  define warning(...) do {                                                    \
80     sudo_debug_printf2(__func__, __FILE__, __LINE__,                           \
81         SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys,  \
82         __VA_ARGS__);                                                          \
83     warning_nodebug(__VA_ARGS__);                                              \
84 } while (0)
85 #  define warningx(...) do {                                                   \
86     sudo_debug_printf2(__func__, __FILE__, __LINE__,                           \
87         SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__);     \
88     warningx_nodebug(__VA_ARGS__);                                             \
89 } while (0)
90 # endif /* __GNUC__ == 2 */
91 # define vfatal(fmt, ap) do {                                          \
92     sudo_debug_vprintf2(__func__, __FILE__, __LINE__,                          \
93         SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
94         (fmt), (ap));                                                          \
95     vfatal_nodebug((fmt), (ap));                                       \
96 } while (0)
97 # define vfatalx(fmt, ap) do {                                         \
98     sudo_debug_vprintf2(__func__, __FILE__, __LINE__,                          \
99         SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), (ap));    \
100     vfatalx_nodebug((fmt), (ap));                                      \
101 } while (0)
102 # define vwarning(fmt, ap) do {                                                \
103     sudo_debug_vprintf2(__func__, __FILE__, __LINE__,                          \
104         SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys,  \
105         (fmt), (ap));                                                          \
106     vwarning_nodebug((fmt), (ap));                                             \
107     warning_restore_locale();                                                  \
108 } while (0)
109 # define vwarningx(fmt, ap) do {                                               \
110     sudo_debug_vprintf2(__func__, __FILE__, __LINE__,                          \
111         SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), (ap));     \
112     vwarningx_nodebug((fmt), (ap));                                            \
113 } while (0)
114 #endif /* SUDO_ERROR_WRAP */
115
116 #if defined(__GNUC__) && __GNUC__ == 2
117 # define fatal_nodebug(fmt...) do {                                    \
118     warning_set_locale();                                                      \
119     fatal2(fmt);                                                       \
120 } while (0)
121 # define fatalx_nodebug(fmt...) do {                                   \
122     warning_set_locale();                                                      \
123     fatalx2(fmt);                                                      \
124 } while (0)
125 # define warning_nodebug(fmt...) do {                                          \
126     warning_set_locale();                                                      \
127     warning2(fmt);                                                             \
128     warning_restore_locale();                                                  \
129 } while (0)
130 # define warningx_nodebug(fmt...) do {                                         \
131     warning_set_locale();                                                      \
132     warningx2(fmt);                                                            \
133     warning_restore_locale();                                                  \
134 } while (0)
135 #else
136 # define fatal_nodebug(...) do {                                               \
137     warning_set_locale();                                                      \
138     fatal2(__VA_ARGS__);                                               \
139 } while (0)
140 # define fatalx_nodebug(...) do {                                              \
141     warning_set_locale();                                                      \
142     fatalx2(__VA_ARGS__);                                              \
143 } while (0)
144 # define warning_nodebug(...) do {                                             \
145     warning_set_locale();                                                      \
146     warning2(__VA_ARGS__);                                                     \
147     warning_restore_locale();                                                  \
148 } while (0)
149 # define warningx_nodebug(...) do {                                            \
150     warning_set_locale();                                                      \
151     warningx2(__VA_ARGS__);                                                    \
152     warning_restore_locale();                                                  \
153 } while (0)
154 #endif /* __GNUC__ == 2 */
155 #define vfatal_nodebug(fmt, ap) do {                                   \
156     warning_set_locale();                                                      \
157     vfatal2((fmt), (ap));                                              \
158 } while (0)
159 #define vfatalx_nodebug(fmt, ap) do {                                  \
160     warning_set_locale();                                                      \
161     vfatalx2((fmt), (ap));                                             \
162 } while (0)
163 #define vwarning_nodebug(fmt, ap) do {                                         \
164     warning_set_locale();                                                      \
165     vwarning2((fmt), (ap));                                                    \
166     warning_restore_locale();                                                  \
167 } while (0)
168 #define vwarningx_nodebug(fmt, ap) do {                                        \
169     warning_set_locale();                                                      \
170     vwarningx2((fmt), (ap));                                                   \
171     warning_restore_locale();                                                  \
172 } while (0)
173
174 #define fatal_setjmp()          (fatal_enable_setjmp(), sigsetjmp(fatal_jmp, 1))
175 #define fatal_longjmp(val)      siglongjmp(fatal_jmp, val)
176
177 extern int (*sudo_printf)(int msg_type, const char *fmt, ...);
178 extern sigjmp_buf fatal_jmp;
179
180 int     fatal_callback_register(void (*func)(void));
181 void    fatal_disable_setjmp(void);
182 void    fatal_enable_setjmp(void);
183 void    fatal2(const char *, ...) __printflike(1, 2) __attribute__((__noreturn__));
184 void    fatalx2(const char *, ...) __printflike(1, 2) __attribute__((__noreturn__));
185 void    vfatal2(const char *, va_list ap) __attribute__((__noreturn__));
186 void    vfatalx2(const char *, va_list ap) __attribute__((__noreturn__));
187 void    warning2(const char *, ...) __printflike(1, 2);
188 void    warningx2(const char *, ...) __printflike(1, 2);
189 void    vwarning2(const char *, va_list ap);
190 void    vwarningx2(const char *, va_list ap);
191 void    warning_set_locale(void);
192 void    warning_restore_locale(void);
193
194 #endif /* _SUDO_ERROR_H_ */