xref: /openbmc/qemu/util/error.c (revision baacf047)
1*baacf047SPaolo Bonzini /*
2*baacf047SPaolo Bonzini  * QEMU Error Objects
3*baacf047SPaolo Bonzini  *
4*baacf047SPaolo Bonzini  * Copyright IBM, Corp. 2011
5*baacf047SPaolo Bonzini  *
6*baacf047SPaolo Bonzini  * Authors:
7*baacf047SPaolo Bonzini  *  Anthony Liguori   <aliguori@us.ibm.com>
8*baacf047SPaolo Bonzini  *
9*baacf047SPaolo Bonzini  * This work is licensed under the terms of the GNU LGPL, version 2.  See
10*baacf047SPaolo Bonzini  * the COPYING.LIB file in the top-level directory.
11*baacf047SPaolo Bonzini  */
12*baacf047SPaolo Bonzini 
13*baacf047SPaolo Bonzini #include "qemu-common.h"
14*baacf047SPaolo Bonzini #include "qapi/error.h"
15*baacf047SPaolo Bonzini #include "qapi/qmp/qjson.h"
16*baacf047SPaolo Bonzini #include "qapi/qmp/qdict.h"
17*baacf047SPaolo Bonzini #include "qapi-types.h"
18*baacf047SPaolo Bonzini #include "qapi/qmp/qerror.h"
19*baacf047SPaolo Bonzini 
20*baacf047SPaolo Bonzini struct Error
21*baacf047SPaolo Bonzini {
22*baacf047SPaolo Bonzini     char *msg;
23*baacf047SPaolo Bonzini     ErrorClass err_class;
24*baacf047SPaolo Bonzini };
25*baacf047SPaolo Bonzini 
26*baacf047SPaolo Bonzini void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
27*baacf047SPaolo Bonzini {
28*baacf047SPaolo Bonzini     Error *err;
29*baacf047SPaolo Bonzini     va_list ap;
30*baacf047SPaolo Bonzini 
31*baacf047SPaolo Bonzini     if (errp == NULL) {
32*baacf047SPaolo Bonzini         return;
33*baacf047SPaolo Bonzini     }
34*baacf047SPaolo Bonzini     assert(*errp == NULL);
35*baacf047SPaolo Bonzini 
36*baacf047SPaolo Bonzini     err = g_malloc0(sizeof(*err));
37*baacf047SPaolo Bonzini 
38*baacf047SPaolo Bonzini     va_start(ap, fmt);
39*baacf047SPaolo Bonzini     err->msg = g_strdup_vprintf(fmt, ap);
40*baacf047SPaolo Bonzini     va_end(ap);
41*baacf047SPaolo Bonzini     err->err_class = err_class;
42*baacf047SPaolo Bonzini 
43*baacf047SPaolo Bonzini     *errp = err;
44*baacf047SPaolo Bonzini }
45*baacf047SPaolo Bonzini 
46*baacf047SPaolo Bonzini void error_set_errno(Error **errp, int os_errno, ErrorClass err_class,
47*baacf047SPaolo Bonzini                      const char *fmt, ...)
48*baacf047SPaolo Bonzini {
49*baacf047SPaolo Bonzini     Error *err;
50*baacf047SPaolo Bonzini     char *msg1;
51*baacf047SPaolo Bonzini     va_list ap;
52*baacf047SPaolo Bonzini 
53*baacf047SPaolo Bonzini     if (errp == NULL) {
54*baacf047SPaolo Bonzini         return;
55*baacf047SPaolo Bonzini     }
56*baacf047SPaolo Bonzini     assert(*errp == NULL);
57*baacf047SPaolo Bonzini 
58*baacf047SPaolo Bonzini     err = g_malloc0(sizeof(*err));
59*baacf047SPaolo Bonzini 
60*baacf047SPaolo Bonzini     va_start(ap, fmt);
61*baacf047SPaolo Bonzini     msg1 = g_strdup_vprintf(fmt, ap);
62*baacf047SPaolo Bonzini     if (os_errno != 0) {
63*baacf047SPaolo Bonzini         err->msg = g_strdup_printf("%s: %s", msg1, strerror(os_errno));
64*baacf047SPaolo Bonzini         g_free(msg1);
65*baacf047SPaolo Bonzini     } else {
66*baacf047SPaolo Bonzini         err->msg = msg1;
67*baacf047SPaolo Bonzini     }
68*baacf047SPaolo Bonzini     va_end(ap);
69*baacf047SPaolo Bonzini     err->err_class = err_class;
70*baacf047SPaolo Bonzini 
71*baacf047SPaolo Bonzini     *errp = err;
72*baacf047SPaolo Bonzini }
73*baacf047SPaolo Bonzini 
74*baacf047SPaolo Bonzini Error *error_copy(const Error *err)
75*baacf047SPaolo Bonzini {
76*baacf047SPaolo Bonzini     Error *err_new;
77*baacf047SPaolo Bonzini 
78*baacf047SPaolo Bonzini     err_new = g_malloc0(sizeof(*err));
79*baacf047SPaolo Bonzini     err_new->msg = g_strdup(err->msg);
80*baacf047SPaolo Bonzini     err_new->err_class = err->err_class;
81*baacf047SPaolo Bonzini 
82*baacf047SPaolo Bonzini     return err_new;
83*baacf047SPaolo Bonzini }
84*baacf047SPaolo Bonzini 
85*baacf047SPaolo Bonzini bool error_is_set(Error **errp)
86*baacf047SPaolo Bonzini {
87*baacf047SPaolo Bonzini     return (errp && *errp);
88*baacf047SPaolo Bonzini }
89*baacf047SPaolo Bonzini 
90*baacf047SPaolo Bonzini ErrorClass error_get_class(const Error *err)
91*baacf047SPaolo Bonzini {
92*baacf047SPaolo Bonzini     return err->err_class;
93*baacf047SPaolo Bonzini }
94*baacf047SPaolo Bonzini 
95*baacf047SPaolo Bonzini const char *error_get_pretty(Error *err)
96*baacf047SPaolo Bonzini {
97*baacf047SPaolo Bonzini     return err->msg;
98*baacf047SPaolo Bonzini }
99*baacf047SPaolo Bonzini 
100*baacf047SPaolo Bonzini void error_free(Error *err)
101*baacf047SPaolo Bonzini {
102*baacf047SPaolo Bonzini     if (err) {
103*baacf047SPaolo Bonzini         g_free(err->msg);
104*baacf047SPaolo Bonzini         g_free(err);
105*baacf047SPaolo Bonzini     }
106*baacf047SPaolo Bonzini }
107*baacf047SPaolo Bonzini 
108*baacf047SPaolo Bonzini void error_propagate(Error **dst_err, Error *local_err)
109*baacf047SPaolo Bonzini {
110*baacf047SPaolo Bonzini     if (dst_err && !*dst_err) {
111*baacf047SPaolo Bonzini         *dst_err = local_err;
112*baacf047SPaolo Bonzini     } else if (local_err) {
113*baacf047SPaolo Bonzini         error_free(local_err);
114*baacf047SPaolo Bonzini     }
115*baacf047SPaolo Bonzini }
116