Luiz Capitulino | d5ec4f2 | 2011-06-01 12:14:49 -0500 | [diff] [blame] | 1 | /* |
| 2 | * QEMU Error Objects |
| 3 | * |
| 4 | * Copyright IBM, Corp. 2011 |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 5 | * Copyright (C) 2011-2015 Red Hat, Inc. |
Luiz Capitulino | d5ec4f2 | 2011-06-01 12:14:49 -0500 | [diff] [blame] | 6 | * |
| 7 | * Authors: |
| 8 | * Anthony Liguori <aliguori@us.ibm.com> |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 9 | * Markus Armbruster <armbru@redhat.com> |
Luiz Capitulino | d5ec4f2 | 2011-06-01 12:14:49 -0500 | [diff] [blame] | 10 | * |
| 11 | * This work is licensed under the terms of the GNU LGPL, version 2. See |
| 12 | * the COPYING.LIB file in the top-level directory. |
| 13 | */ |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 14 | |
| 15 | /* |
| 16 | * Error reporting system loosely patterned after Glib's GError. |
| 17 | * |
| 18 | * Create an error: |
| 19 | * error_setg(&err, "situation normal, all fouled up"); |
| 20 | * |
Markus Armbruster | f4d0064 | 2015-12-18 16:35:08 +0100 | [diff] [blame] | 21 | * Create an error and add additional explanation: |
| 22 | * error_setg(&err, "invalid quark"); |
| 23 | * error_append_hint(&err, "Valid quarks are up, down, strange, " |
| 24 | * "charm, top, bottom.\n"); |
| 25 | * |
| 26 | * Do *not* contract this to |
| 27 | * error_setg(&err, "invalid quark\n" |
| 28 | * "Valid quarks are up, down, strange, charm, top, bottom."); |
| 29 | * |
Markus Armbruster | 10303f0 | 2016-02-03 19:03:47 +0100 | [diff] [blame] | 30 | * Report an error to the current monitor if we have one, else stderr: |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 31 | * error_report_err(err); |
| 32 | * This frees the error object. |
| 33 | * |
Markus Armbruster | 10303f0 | 2016-02-03 19:03:47 +0100 | [diff] [blame] | 34 | * Likewise, but with additional text prepended: |
Markus Armbruster | 8277d2a | 2015-12-18 16:35:12 +0100 | [diff] [blame] | 35 | * error_reportf_err(err, "Could not frobnicate '%s': ", name); |
| 36 | * |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 37 | * Report an error somewhere else: |
| 38 | * const char *msg = error_get_pretty(err); |
| 39 | * do with msg what needs to be done... |
| 40 | * error_free(err); |
Markus Armbruster | f4d0064 | 2015-12-18 16:35:08 +0100 | [diff] [blame] | 41 | * Note that this loses hints added with error_append_hint(). |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 42 | * |
| 43 | * Handle an error without reporting it (just for completeness): |
| 44 | * error_free(err); |
| 45 | * |
Eric Blake | a12a5a1 | 2015-11-05 23:35:31 -0700 | [diff] [blame] | 46 | * Assert that an expected error occurred, but clean it up without |
| 47 | * reporting it (primarily useful in testsuites): |
| 48 | * error_free_or_abort(&err); |
| 49 | * |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 50 | * Pass an existing error to the caller: |
| 51 | * error_propagate(errp, err); |
| 52 | * where Error **errp is a parameter, by convention the last one. |
| 53 | * |
Markus Armbruster | 8277d2a | 2015-12-18 16:35:12 +0100 | [diff] [blame] | 54 | * Pass an existing error to the caller with the message modified: |
Markus Armbruster | 4b57664 | 2018-10-17 10:26:25 +0200 | [diff] [blame] | 55 | * error_propagate_prepend(errp, err); |
| 56 | * |
| 57 | * Avoid |
Markus Armbruster | 8277d2a | 2015-12-18 16:35:12 +0100 | [diff] [blame] | 58 | * error_propagate(errp, err); |
| 59 | * error_prepend(errp, "Could not frobnicate '%s': ", name); |
Markus Armbruster | 4b57664 | 2018-10-17 10:26:25 +0200 | [diff] [blame] | 60 | * because this fails to prepend when @errp is &error_fatal. |
Markus Armbruster | 8277d2a | 2015-12-18 16:35:12 +0100 | [diff] [blame] | 61 | * |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 62 | * Create a new error and pass it to the caller: |
| 63 | * error_setg(errp, "situation normal, all fouled up"); |
| 64 | * |
| 65 | * Call a function and receive an error from it: |
| 66 | * Error *err = NULL; |
| 67 | * foo(arg, &err); |
| 68 | * if (err) { |
| 69 | * handle the error... |
| 70 | * } |
| 71 | * |
| 72 | * Call a function ignoring errors: |
| 73 | * foo(arg, NULL); |
| 74 | * |
| 75 | * Call a function aborting on errors: |
| 76 | * foo(arg, &error_abort); |
| 77 | * |
Markus Armbruster | a29a37b | 2015-09-11 16:51:42 +0200 | [diff] [blame] | 78 | * Call a function treating errors as fatal: |
| 79 | * foo(arg, &error_fatal); |
| 80 | * |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 81 | * Receive an error and pass it on to the caller: |
| 82 | * Error *err = NULL; |
| 83 | * foo(arg, &err); |
| 84 | * if (err) { |
| 85 | * handle the error... |
| 86 | * error_propagate(errp, err); |
| 87 | * } |
| 88 | * where Error **errp is a parameter, by convention the last one. |
| 89 | * |
| 90 | * Do *not* "optimize" this to |
| 91 | * foo(arg, errp); |
| 92 | * if (*errp) { // WRONG! |
| 93 | * handle the error... |
| 94 | * } |
| 95 | * because errp may be NULL! |
| 96 | * |
| 97 | * But when all you do with the error is pass it on, please use |
| 98 | * foo(arg, errp); |
| 99 | * for readability. |
Markus Armbruster | 8d780f4 | 2015-11-17 17:05:49 +0100 | [diff] [blame] | 100 | * |
| 101 | * Receive and accumulate multiple errors (first one wins): |
| 102 | * Error *err = NULL, *local_err = NULL; |
| 103 | * foo(arg, &err); |
| 104 | * bar(arg, &local_err); |
| 105 | * error_propagate(&err, local_err); |
| 106 | * if (err) { |
| 107 | * handle the error... |
| 108 | * } |
| 109 | * |
| 110 | * Do *not* "optimize" this to |
| 111 | * foo(arg, &err); |
| 112 | * bar(arg, &err); // WRONG! |
| 113 | * if (err) { |
| 114 | * handle the error... |
| 115 | * } |
| 116 | * because this may pass a non-null err to bar(). |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 117 | */ |
| 118 | |
Luiz Capitulino | d5ec4f2 | 2011-06-01 12:14:49 -0500 | [diff] [blame] | 119 | #ifndef ERROR_H |
| 120 | #define ERROR_H |
| 121 | |
Markus Armbruster | 9af2398 | 2018-02-11 10:36:01 +0100 | [diff] [blame] | 122 | #include "qapi/qapi-types-common.h" |
Luiz Capitulino | d5ec4f2 | 2011-06-01 12:14:49 -0500 | [diff] [blame] | 123 | |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 124 | /* |
Eric Blake | f22a28b | 2015-11-18 01:53:00 -0700 | [diff] [blame] | 125 | * Overall category of an error. |
| 126 | * Based on the qapi type QapiErrorClass, but reproduced here for nicer |
| 127 | * enum names. |
| 128 | */ |
| 129 | typedef enum ErrorClass { |
Eric Blake | d20a580 | 2015-11-18 01:53:01 -0700 | [diff] [blame] | 130 | ERROR_CLASS_GENERIC_ERROR = QAPI_ERROR_CLASS_GENERICERROR, |
| 131 | ERROR_CLASS_COMMAND_NOT_FOUND = QAPI_ERROR_CLASS_COMMANDNOTFOUND, |
Eric Blake | d20a580 | 2015-11-18 01:53:01 -0700 | [diff] [blame] | 132 | ERROR_CLASS_DEVICE_NOT_ACTIVE = QAPI_ERROR_CLASS_DEVICENOTACTIVE, |
| 133 | ERROR_CLASS_DEVICE_NOT_FOUND = QAPI_ERROR_CLASS_DEVICENOTFOUND, |
| 134 | ERROR_CLASS_KVM_MISSING_CAP = QAPI_ERROR_CLASS_KVMMISSINGCAP, |
Eric Blake | f22a28b | 2015-11-18 01:53:00 -0700 | [diff] [blame] | 135 | } ErrorClass; |
| 136 | |
| 137 | /* |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 138 | * Get @err's human-readable error message. |
Luiz Capitulino | d5ec4f2 | 2011-06-01 12:14:49 -0500 | [diff] [blame] | 139 | */ |
Daniel P. Berrange | d59ce6f | 2016-04-27 11:05:00 +0100 | [diff] [blame] | 140 | const char *error_get_pretty(const Error *err); |
Luiz Capitulino | d5ec4f2 | 2011-06-01 12:14:49 -0500 | [diff] [blame] | 141 | |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 142 | /* |
| 143 | * Get @err's error class. |
| 144 | * Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is |
| 145 | * strongly discouraged. |
| 146 | */ |
| 147 | ErrorClass error_get_class(const Error *err); |
| 148 | |
| 149 | /* |
| 150 | * Create a new error object and assign it to *@errp. |
| 151 | * If @errp is NULL, the error is ignored. Don't bother creating one |
| 152 | * then. |
| 153 | * If @errp is &error_abort, print a suitable message and abort(). |
Markus Armbruster | a29a37b | 2015-09-11 16:51:42 +0200 | [diff] [blame] | 154 | * If @errp is &error_fatal, print a suitable message and exit(1). |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 155 | * If @errp is anything else, *@errp must be NULL. |
| 156 | * The new error's class is ERROR_CLASS_GENERIC_ERROR, and its |
| 157 | * human-readable error message is made from printf-style @fmt, ... |
Markus Armbruster | f4d0064 | 2015-12-18 16:35:08 +0100 | [diff] [blame] | 158 | * The resulting message should be a single phrase, with no newline or |
| 159 | * trailing punctuation. |
Markus Armbruster | 10303f0 | 2016-02-03 19:03:47 +0100 | [diff] [blame] | 160 | * Please don't error_setg(&error_fatal, ...), use error_report() and |
| 161 | * exit(), because that's more obvious. |
| 162 | * Likewise, don't error_setg(&error_abort, ...), use assert(). |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 163 | */ |
Markus Armbruster | 1e9b65b | 2015-06-19 19:21:59 +0200 | [diff] [blame] | 164 | #define error_setg(errp, fmt, ...) \ |
| 165 | error_setg_internal((errp), __FILE__, __LINE__, __func__, \ |
| 166 | (fmt), ## __VA_ARGS__) |
| 167 | void error_setg_internal(Error **errp, |
| 168 | const char *src, int line, const char *func, |
| 169 | const char *fmt, ...) |
| 170 | GCC_FMT_ATTR(5, 6); |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 171 | |
| 172 | /* |
| 173 | * Just like error_setg(), with @os_error info added to the message. |
| 174 | * If @os_error is non-zero, ": " + strerror(os_error) is appended to |
| 175 | * the human-readable error message. |
Sascha Silbe | 98cb89a | 2016-07-27 11:24:26 +0200 | [diff] [blame] | 176 | * |
| 177 | * The value of errno (which usually can get clobbered by almost any |
| 178 | * function call) will be preserved. |
Paolo Bonzini | 680d16d | 2012-10-02 09:00:45 +0200 | [diff] [blame] | 179 | */ |
Markus Armbruster | 1e9b65b | 2015-06-19 19:21:59 +0200 | [diff] [blame] | 180 | #define error_setg_errno(errp, os_error, fmt, ...) \ |
| 181 | error_setg_errno_internal((errp), __FILE__, __LINE__, __func__, \ |
| 182 | (os_error), (fmt), ## __VA_ARGS__) |
| 183 | void error_setg_errno_internal(Error **errp, |
| 184 | const char *fname, int line, const char *func, |
| 185 | int os_error, const char *fmt, ...) |
| 186 | GCC_FMT_ATTR(6, 7); |
Paolo Bonzini | 680d16d | 2012-10-02 09:00:45 +0200 | [diff] [blame] | 187 | |
Tomoki Sekiyama | 20840d4 | 2013-08-07 11:40:11 -0400 | [diff] [blame] | 188 | #ifdef _WIN32 |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 189 | /* |
| 190 | * Just like error_setg(), with @win32_error info added to the message. |
| 191 | * If @win32_error is non-zero, ": " + g_win32_error_message(win32_err) |
| 192 | * is appended to the human-readable error message. |
Tomoki Sekiyama | 20840d4 | 2013-08-07 11:40:11 -0400 | [diff] [blame] | 193 | */ |
Markus Armbruster | 1e9b65b | 2015-06-19 19:21:59 +0200 | [diff] [blame] | 194 | #define error_setg_win32(errp, win32_err, fmt, ...) \ |
| 195 | error_setg_win32_internal((errp), __FILE__, __LINE__, __func__, \ |
| 196 | (win32_err), (fmt), ## __VA_ARGS__) |
| 197 | void error_setg_win32_internal(Error **errp, |
| 198 | const char *src, int line, const char *func, |
| 199 | int win32_err, const char *fmt, ...) |
| 200 | GCC_FMT_ATTR(6, 7); |
Tomoki Sekiyama | 20840d4 | 2013-08-07 11:40:11 -0400 | [diff] [blame] | 201 | #endif |
| 202 | |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 203 | /* |
| 204 | * Propagate error object (if any) from @local_err to @dst_errp. |
| 205 | * If @local_err is NULL, do nothing (because there's nothing to |
| 206 | * propagate). |
| 207 | * Else, if @dst_errp is NULL, errors are being ignored. Free the |
| 208 | * error object. |
| 209 | * Else, if @dst_errp is &error_abort, print a suitable message and |
| 210 | * abort(). |
Markus Armbruster | a29a37b | 2015-09-11 16:51:42 +0200 | [diff] [blame] | 211 | * Else, if @dst_errp is &error_fatal, print a suitable message and |
| 212 | * exit(1). |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 213 | * Else, if @dst_errp already contains an error, ignore this one: free |
| 214 | * the error object. |
| 215 | * Else, move the error object from @local_err to *@dst_errp. |
| 216 | * On return, @local_err is invalid. |
Markus Armbruster | 10303f0 | 2016-02-03 19:03:47 +0100 | [diff] [blame] | 217 | * Please don't error_propagate(&error_fatal, ...), use |
| 218 | * error_report_err() and exit(), because that's more obvious. |
Luiz Capitulino | 75d789f | 2012-08-29 11:20:57 -0300 | [diff] [blame] | 219 | */ |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 220 | void error_propagate(Error **dst_errp, Error *local_err); |
Luiz Capitulino | 75d789f | 2012-08-29 11:20:57 -0300 | [diff] [blame] | 221 | |
Markus Armbruster | 4b57664 | 2018-10-17 10:26:25 +0200 | [diff] [blame] | 222 | |
| 223 | /* |
| 224 | * Propagate error object (if any) with some text prepended. |
| 225 | * Behaves like |
| 226 | * error_prepend(&local_err, fmt, ...); |
| 227 | * error_propagate(dst_errp, local_err); |
| 228 | */ |
| 229 | void error_propagate_prepend(Error **dst_errp, Error *local_err, |
| 230 | const char *fmt, ...); |
| 231 | |
Markus Armbruster | 8277d2a | 2015-12-18 16:35:12 +0100 | [diff] [blame] | 232 | /* |
| 233 | * Prepend some text to @errp's human-readable error message. |
| 234 | * The text is made by formatting @fmt, @ap like vprintf(). |
| 235 | */ |
| 236 | void error_vprepend(Error **errp, const char *fmt, va_list ap); |
| 237 | |
| 238 | /* |
| 239 | * Prepend some text to @errp's human-readable error message. |
| 240 | * The text is made by formatting @fmt, ... like printf(). |
| 241 | */ |
| 242 | void error_prepend(Error **errp, const char *fmt, ...) |
| 243 | GCC_FMT_ATTR(2, 3); |
| 244 | |
| 245 | /* |
Eric Blake | 50b7b00 | 2015-09-10 10:19:16 -0600 | [diff] [blame] | 246 | * Append a printf-style human-readable explanation to an existing error. |
Markus Armbruster | 508de47 | 2017-08-10 12:06:28 +0200 | [diff] [blame] | 247 | * If the error is later reported to a human user with |
| 248 | * error_report_err() or warn_report_err(), the hints will be shown, |
| 249 | * too. If it's reported via QMP, the hints will be ignored. |
| 250 | * Intended use is adding helpful hints on the human user interface, |
| 251 | * e.g. a list of valid values. It's not for clarifying a confusing |
| 252 | * error message. |
Markus Armbruster | f4d0064 | 2015-12-18 16:35:08 +0100 | [diff] [blame] | 253 | * @errp may be NULL, but not &error_fatal or &error_abort. |
| 254 | * Trivially the case if you call it only after error_setg() or |
| 255 | * error_propagate(). |
| 256 | * May be called multiple times. The resulting hint should end with a |
| 257 | * newline. |
Eric Blake | 50b7b00 | 2015-09-10 10:19:16 -0600 | [diff] [blame] | 258 | */ |
| 259 | void error_append_hint(Error **errp, const char *fmt, ...) |
| 260 | GCC_FMT_ATTR(2, 3); |
| 261 | |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 262 | /* |
| 263 | * Convenience function to report open() failure. |
Luiz Capitulino | 54028d7 | 2013-06-07 14:24:49 -0400 | [diff] [blame] | 264 | */ |
Markus Armbruster | 1e9b65b | 2015-06-19 19:21:59 +0200 | [diff] [blame] | 265 | #define error_setg_file_open(errp, os_errno, filename) \ |
| 266 | error_setg_file_open_internal((errp), __FILE__, __LINE__, __func__, \ |
| 267 | (os_errno), (filename)) |
| 268 | void error_setg_file_open_internal(Error **errp, |
| 269 | const char *src, int line, const char *func, |
| 270 | int os_errno, const char *filename); |
Luiz Capitulino | 54028d7 | 2013-06-07 14:24:49 -0400 | [diff] [blame] | 271 | |
Luiz Capitulino | ea25fbc | 2012-08-01 16:29:38 -0300 | [diff] [blame] | 272 | /* |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 273 | * Return an exact copy of @err. |
Luiz Capitulino | 79020cf | 2011-12-05 16:04:05 -0200 | [diff] [blame] | 274 | */ |
| 275 | Error *error_copy(const Error *err); |
| 276 | |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 277 | /* |
| 278 | * Free @err. |
| 279 | * @err may be NULL. |
Luiz Capitulino | d5ec4f2 | 2011-06-01 12:14:49 -0500 | [diff] [blame] | 280 | */ |
| 281 | void error_free(Error *err); |
| 282 | |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 283 | /* |
Eric Blake | a12a5a1 | 2015-11-05 23:35:31 -0700 | [diff] [blame] | 284 | * Convenience function to assert that *@errp is set, then silently free it. |
| 285 | */ |
| 286 | void error_free_or_abort(Error **errp); |
| 287 | |
| 288 | /* |
Alistair Francis | e43ead1 | 2017-07-12 06:57:52 -0700 | [diff] [blame] | 289 | * Convenience function to warn_report() and free @err. |
Markus Armbruster | 508de47 | 2017-08-10 12:06:28 +0200 | [diff] [blame] | 290 | * The report includes hints added with error_append_hint(). |
Alistair Francis | e43ead1 | 2017-07-12 06:57:52 -0700 | [diff] [blame] | 291 | */ |
| 292 | void warn_report_err(Error *err); |
| 293 | |
| 294 | /* |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 295 | * Convenience function to error_report() and free @err. |
Markus Armbruster | 508de47 | 2017-08-10 12:06:28 +0200 | [diff] [blame] | 296 | * The report includes hints added with error_append_hint(). |
Peter Crosthwaite | 5d24ee7 | 2014-01-01 18:46:59 -0800 | [diff] [blame] | 297 | */ |
Markus Armbruster | f4d0064 | 2015-12-18 16:35:08 +0100 | [diff] [blame] | 298 | void error_report_err(Error *err); |
Peter Crosthwaite | 5d24ee7 | 2014-01-01 18:46:59 -0800 | [diff] [blame] | 299 | |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 300 | /* |
Alistair Francis | e43ead1 | 2017-07-12 06:57:52 -0700 | [diff] [blame] | 301 | * Convenience function to error_prepend(), warn_report() and free @err. |
| 302 | */ |
| 303 | void warn_reportf_err(Error *err, const char *fmt, ...) |
| 304 | GCC_FMT_ATTR(2, 3); |
| 305 | |
| 306 | /* |
Markus Armbruster | 8277d2a | 2015-12-18 16:35:12 +0100 | [diff] [blame] | 307 | * Convenience function to error_prepend(), error_report() and free @err. |
| 308 | */ |
| 309 | void error_reportf_err(Error *err, const char *fmt, ...) |
| 310 | GCC_FMT_ATTR(2, 3); |
| 311 | |
| 312 | /* |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 313 | * Just like error_setg(), except you get to specify the error class. |
| 314 | * Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is |
| 315 | * strongly discouraged. |
| 316 | */ |
Markus Armbruster | 1e9b65b | 2015-06-19 19:21:59 +0200 | [diff] [blame] | 317 | #define error_set(errp, err_class, fmt, ...) \ |
| 318 | error_set_internal((errp), __FILE__, __LINE__, __func__, \ |
| 319 | (err_class), (fmt), ## __VA_ARGS__) |
| 320 | void error_set_internal(Error **errp, |
| 321 | const char *src, int line, const char *func, |
| 322 | ErrorClass err_class, const char *fmt, ...) |
| 323 | GCC_FMT_ATTR(6, 7); |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 324 | |
| 325 | /* |
Markus Armbruster | 10303f0 | 2016-02-03 19:03:47 +0100 | [diff] [blame] | 326 | * Special error destination to abort on error. |
| 327 | * See error_setg() and error_propagate() for details. |
Markus Armbruster | edf6f3b | 2015-06-19 18:29:24 +0200 | [diff] [blame] | 328 | */ |
Peter Crosthwaite | 5d24ee7 | 2014-01-01 18:46:59 -0800 | [diff] [blame] | 329 | extern Error *error_abort; |
| 330 | |
Markus Armbruster | a29a37b | 2015-09-11 16:51:42 +0200 | [diff] [blame] | 331 | /* |
Markus Armbruster | 10303f0 | 2016-02-03 19:03:47 +0100 | [diff] [blame] | 332 | * Special error destination to exit(1) on error. |
| 333 | * See error_setg() and error_propagate() for details. |
Markus Armbruster | a29a37b | 2015-09-11 16:51:42 +0200 | [diff] [blame] | 334 | */ |
| 335 | extern Error *error_fatal; |
| 336 | |
Luiz Capitulino | d5ec4f2 | 2011-06-01 12:14:49 -0500 | [diff] [blame] | 337 | #endif |