#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "qemu-common.h"
#include "qemu/error-report.h"
struct Error
Error *error_abort;
Error *error_fatal;
+Error *error_warn;
-static void error_handle_fatal(Error **errp, Error *err)
+static void error_handle(Error **errp, Error *err)
{
if (errp == &error_abort) {
fprintf(stderr, "Unexpected error in %s() at %s:%d:\n",
err->func, err->src, err->line);
- error_report_err(err);
+ error_report("%s", error_get_pretty(err));
+ if (err->hint) {
+ error_printf("%s", err->hint->str);
+ }
abort();
}
if (errp == &error_fatal) {
error_report_err(err);
exit(1);
}
+ if (errp == &error_warn) {
+ warn_report_err(err);
+ } else if (errp && !*errp) {
+ *errp = err;
+ } else {
+ error_free(err);
+ }
}
+G_GNUC_PRINTF(6, 0)
static void error_setv(Error **errp,
const char *src, int line, const char *func,
ErrorClass err_class, const char *fmt, va_list ap,
err->line = line;
err->func = func;
- error_handle_fatal(errp, err);
- *errp = err;
+ error_handle(errp, err);
errno = saved_errno;
}
va_list ap;
int saved_errno = errno;
- if (errp == NULL) {
- return;
- }
-
va_start(ap, fmt);
error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap,
os_errno != 0 ? strerror(os_errno) : NULL);
"Could not open '%s'", filename);
}
-void error_vprepend(Error **errp, const char *fmt, va_list ap)
+void error_vprepend(Error *const *errp, const char *fmt, va_list ap)
{
GString *newmsg;
newmsg = g_string_new(NULL);
g_string_vprintf(newmsg, fmt, ap);
g_string_append(newmsg, (*errp)->msg);
+ g_free((*errp)->msg);
(*errp)->msg = g_string_free(newmsg, 0);
}
-void error_prepend(Error **errp, const char *fmt, ...)
+void error_prepend(Error *const *errp, const char *fmt, ...)
{
va_list ap;
va_end(ap);
}
-void error_append_hint(Error **errp, const char *fmt, ...)
+void error_append_hint(Error *const *errp, const char *fmt, ...)
{
va_list ap;
int saved_errno = errno;
return err->err_class;
}
-const char *error_get_pretty(Error *err)
+const char *error_get_pretty(const Error *err)
{
return err->msg;
}
{
error_report("%s", error_get_pretty(err));
if (err->hint) {
- error_printf_unless_qmp("%s", err->hint->str);
+ error_printf("%s", err->hint->str);
+ }
+ error_free(err);
+}
+
+void warn_report_err(Error *err)
+{
+ warn_report("%s", error_get_pretty(err));
+ if (err->hint) {
+ error_printf("%s", err->hint->str);
}
error_free(err);
}
error_report_err(err);
}
+
+void warn_reportf_err(Error *err, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ error_vprepend(&err, fmt, ap);
+ va_end(ap);
+ warn_report_err(err);
+}
+
void error_free(Error *err)
{
if (err) {
if (!local_err) {
return;
}
- error_handle_fatal(dst_errp, local_err);
+ error_handle(dst_errp, local_err);
+}
+
+void error_propagate_prepend(Error **dst_errp, Error *err,
+ const char *fmt, ...)
+{
+ va_list ap;
+
if (dst_errp && !*dst_errp) {
- *dst_errp = local_err;
- } else {
- error_free(local_err);
- }
+ va_start(ap, fmt);
+ error_vprepend(&err, fmt, ap);
+ va_end(ap);
+ } /* else error is being ignored, don't bother with prepending */
+ error_propagate(dst_errp, err);
}