• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * QError Module
3  *
4  * Copyright (C) 2009 Red Hat Inc.
5  *
6  * Authors:
7  *  Luiz Capitulino <lcapitulino@redhat.com>
8  *
9  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10  * See the COPYING.LIB file in the top-level directory.
11  */
12 
13 #include "monitor/monitor.h"
14 #include "qapi/qmp/qjson.h"
15 #include "qapi/qmp/qerror.h"
16 #include "qemu-common.h"
17 
18 static void qerror_destroy_obj(QObject *obj);
19 
20 static const QType qerror_type = {
21     .code = QTYPE_QERROR,
22     .destroy = qerror_destroy_obj,
23 };
24 
25 /**
26  * qerror_new(): Create a new QError
27  *
28  * Return strong reference.
29  */
qerror_new(void)30 static QError *qerror_new(void)
31 {
32     QError *qerr;
33 
34     qerr = g_malloc0(sizeof(*qerr));
35     QOBJECT_INIT(qerr, &qerror_type);
36 
37     return qerr;
38 }
39 
40 /**
41  * qerror_from_info(): Create a new QError from error information
42  *
43  * Return strong reference.
44  */
45 static QError * GCC_FMT_ATTR(2, 0)
qerror_from_info(ErrorClass err_class,const char * fmt,va_list * va)46 qerror_from_info(ErrorClass err_class, const char *fmt, va_list *va)
47 {
48     QError *qerr;
49 
50     qerr = qerror_new();
51     loc_save(&qerr->loc);
52 
53     qerr->err_msg = g_strdup_vprintf(fmt, *va);
54     qerr->err_class = err_class;
55 
56     return qerr;
57 }
58 
59 /**
60  * qerror_human(): Format QError data into human-readable string.
61  */
qerror_human(const QError * qerror)62 QString *qerror_human(const QError *qerror)
63 {
64     return qstring_from_str(qerror->err_msg);
65 }
66 
67 /**
68  * qerror_print(): Print QError data
69  *
70  * This function will print the member 'desc' of the specified QError object,
71  * it uses error_report() for this, so that the output is routed to the right
72  * place (ie. stderr or Monitor's device).
73  */
qerror_print(QError * qerror)74 static void qerror_print(QError *qerror)
75 {
76     QString *qstring = qerror_human(qerror);
77     loc_push_restore(&qerror->loc);
78     error_report("%s", qstring_get_str(qstring));
79     loc_pop(&qerror->loc);
80     QDECREF(qstring);
81 }
82 
qerror_report(ErrorClass eclass,const char * fmt,...)83 void qerror_report(ErrorClass eclass, const char *fmt, ...)
84 {
85     va_list va;
86     QError *qerror;
87 
88     va_start(va, fmt);
89     qerror = qerror_from_info(eclass, fmt, &va);
90     va_end(va);
91 
92     if (monitor_cur_is_qmp()) {
93         monitor_set_error(cur_mon, qerror);
94     } else {
95         qerror_print(qerror);
96         QDECREF(qerror);
97     }
98 }
99 
100 /* Evil... */
101 struct Error
102 {
103     char *msg;
104     ErrorClass err_class;
105 };
106 
qerror_report_err(Error * err)107 void qerror_report_err(Error *err)
108 {
109     QError *qerr;
110 
111     qerr = qerror_new();
112     loc_save(&qerr->loc);
113     qerr->err_msg = g_strdup(err->msg);
114     qerr->err_class = err->err_class;
115 
116     if (monitor_cur_is_qmp()) {
117         monitor_set_error(cur_mon, qerr);
118     } else {
119         qerror_print(qerr);
120         QDECREF(qerr);
121     }
122 }
123 
assert_no_error(Error * err)124 void assert_no_error(Error *err)
125 {
126     if (err) {
127         qerror_report_err(err);
128         abort();
129     }
130 }
131 
132 /**
133  * qobject_to_qerror(): Convert a QObject into a QError
134  */
qobject_to_qerror(const QObject * obj)135 static QError *qobject_to_qerror(const QObject *obj)
136 {
137     if (qobject_type(obj) != QTYPE_QERROR) {
138         return NULL;
139     }
140 
141     return container_of(obj, QError, base);
142 }
143 
144 /**
145  * qerror_destroy_obj(): Free all memory allocated by a QError
146  */
qerror_destroy_obj(QObject * obj)147 static void qerror_destroy_obj(QObject *obj)
148 {
149     QError *qerr;
150 
151     assert(obj != NULL);
152     qerr = qobject_to_qerror(obj);
153 
154     g_free(qerr->err_msg);
155     g_free(qerr);
156 }
157