xref: /openbmc/qemu/util/error.c (revision 20840d4c)
1baacf047SPaolo Bonzini /*
2baacf047SPaolo Bonzini  * QEMU Error Objects
3baacf047SPaolo Bonzini  *
4baacf047SPaolo Bonzini  * Copyright IBM, Corp. 2011
5baacf047SPaolo Bonzini  *
6baacf047SPaolo Bonzini  * Authors:
7baacf047SPaolo Bonzini  *  Anthony Liguori   <aliguori@us.ibm.com>
8baacf047SPaolo Bonzini  *
9baacf047SPaolo Bonzini  * This work is licensed under the terms of the GNU LGPL, version 2.  See
10baacf047SPaolo Bonzini  * the COPYING.LIB file in the top-level directory.
11baacf047SPaolo Bonzini  */
12baacf047SPaolo Bonzini 
13baacf047SPaolo Bonzini #include "qemu-common.h"
14baacf047SPaolo Bonzini #include "qapi/error.h"
15baacf047SPaolo Bonzini #include "qapi/qmp/qjson.h"
16baacf047SPaolo Bonzini #include "qapi/qmp/qdict.h"
17baacf047SPaolo Bonzini #include "qapi-types.h"
18baacf047SPaolo Bonzini #include "qapi/qmp/qerror.h"
19baacf047SPaolo Bonzini 
20baacf047SPaolo Bonzini struct Error
21baacf047SPaolo Bonzini {
22baacf047SPaolo Bonzini     char *msg;
23baacf047SPaolo Bonzini     ErrorClass err_class;
24baacf047SPaolo Bonzini };
25baacf047SPaolo Bonzini 
26baacf047SPaolo Bonzini void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
27baacf047SPaolo Bonzini {
28baacf047SPaolo Bonzini     Error *err;
29baacf047SPaolo Bonzini     va_list ap;
30baacf047SPaolo Bonzini 
31baacf047SPaolo Bonzini     if (errp == NULL) {
32baacf047SPaolo Bonzini         return;
33baacf047SPaolo Bonzini     }
34baacf047SPaolo Bonzini     assert(*errp == NULL);
35baacf047SPaolo Bonzini 
36baacf047SPaolo Bonzini     err = g_malloc0(sizeof(*err));
37baacf047SPaolo Bonzini 
38baacf047SPaolo Bonzini     va_start(ap, fmt);
39baacf047SPaolo Bonzini     err->msg = g_strdup_vprintf(fmt, ap);
40baacf047SPaolo Bonzini     va_end(ap);
41baacf047SPaolo Bonzini     err->err_class = err_class;
42baacf047SPaolo Bonzini 
43baacf047SPaolo Bonzini     *errp = err;
44baacf047SPaolo Bonzini }
45baacf047SPaolo Bonzini 
46baacf047SPaolo Bonzini void error_set_errno(Error **errp, int os_errno, ErrorClass err_class,
47baacf047SPaolo Bonzini                      const char *fmt, ...)
48baacf047SPaolo Bonzini {
49baacf047SPaolo Bonzini     Error *err;
50baacf047SPaolo Bonzini     char *msg1;
51baacf047SPaolo Bonzini     va_list ap;
52baacf047SPaolo Bonzini 
53baacf047SPaolo Bonzini     if (errp == NULL) {
54baacf047SPaolo Bonzini         return;
55baacf047SPaolo Bonzini     }
56baacf047SPaolo Bonzini     assert(*errp == NULL);
57baacf047SPaolo Bonzini 
58baacf047SPaolo Bonzini     err = g_malloc0(sizeof(*err));
59baacf047SPaolo Bonzini 
60baacf047SPaolo Bonzini     va_start(ap, fmt);
61baacf047SPaolo Bonzini     msg1 = g_strdup_vprintf(fmt, ap);
62baacf047SPaolo Bonzini     if (os_errno != 0) {
63baacf047SPaolo Bonzini         err->msg = g_strdup_printf("%s: %s", msg1, strerror(os_errno));
64baacf047SPaolo Bonzini         g_free(msg1);
65baacf047SPaolo Bonzini     } else {
66baacf047SPaolo Bonzini         err->msg = msg1;
67baacf047SPaolo Bonzini     }
68baacf047SPaolo Bonzini     va_end(ap);
69baacf047SPaolo Bonzini     err->err_class = err_class;
70baacf047SPaolo Bonzini 
71baacf047SPaolo Bonzini     *errp = err;
72baacf047SPaolo Bonzini }
73baacf047SPaolo Bonzini 
7454028d75SLuiz Capitulino void error_setg_file_open(Error **errp, int os_errno, const char *filename)
7554028d75SLuiz Capitulino {
7654028d75SLuiz Capitulino     error_setg_errno(errp, os_errno, "Could not open '%s'", filename);
7754028d75SLuiz Capitulino }
7854028d75SLuiz Capitulino 
79*20840d4cSTomoki Sekiyama #ifdef _WIN32
80*20840d4cSTomoki Sekiyama 
81*20840d4cSTomoki Sekiyama void error_set_win32(Error **errp, int win32_err, ErrorClass err_class,
82*20840d4cSTomoki Sekiyama                      const char *fmt, ...)
83*20840d4cSTomoki Sekiyama {
84*20840d4cSTomoki Sekiyama     Error *err;
85*20840d4cSTomoki Sekiyama     char *msg1;
86*20840d4cSTomoki Sekiyama     va_list ap;
87*20840d4cSTomoki Sekiyama 
88*20840d4cSTomoki Sekiyama     if (errp == NULL) {
89*20840d4cSTomoki Sekiyama         return;
90*20840d4cSTomoki Sekiyama     }
91*20840d4cSTomoki Sekiyama     assert(*errp == NULL);
92*20840d4cSTomoki Sekiyama 
93*20840d4cSTomoki Sekiyama     err = g_malloc0(sizeof(*err));
94*20840d4cSTomoki Sekiyama 
95*20840d4cSTomoki Sekiyama     va_start(ap, fmt);
96*20840d4cSTomoki Sekiyama     msg1 = g_strdup_vprintf(fmt, ap);
97*20840d4cSTomoki Sekiyama     if (win32_err != 0) {
98*20840d4cSTomoki Sekiyama         char *msg2 = g_win32_error_message(win32_err);
99*20840d4cSTomoki Sekiyama         err->msg = g_strdup_printf("%s: %s (error: %x)", msg1, msg2,
100*20840d4cSTomoki Sekiyama                                    (unsigned)win32_err);
101*20840d4cSTomoki Sekiyama         g_free(msg2);
102*20840d4cSTomoki Sekiyama         g_free(msg1);
103*20840d4cSTomoki Sekiyama     } else {
104*20840d4cSTomoki Sekiyama         err->msg = msg1;
105*20840d4cSTomoki Sekiyama     }
106*20840d4cSTomoki Sekiyama     va_end(ap);
107*20840d4cSTomoki Sekiyama     err->err_class = err_class;
108*20840d4cSTomoki Sekiyama 
109*20840d4cSTomoki Sekiyama     *errp = err;
110*20840d4cSTomoki Sekiyama }
111*20840d4cSTomoki Sekiyama 
112*20840d4cSTomoki Sekiyama #endif
113*20840d4cSTomoki Sekiyama 
114baacf047SPaolo Bonzini Error *error_copy(const Error *err)
115baacf047SPaolo Bonzini {
116baacf047SPaolo Bonzini     Error *err_new;
117baacf047SPaolo Bonzini 
118baacf047SPaolo Bonzini     err_new = g_malloc0(sizeof(*err));
119baacf047SPaolo Bonzini     err_new->msg = g_strdup(err->msg);
120baacf047SPaolo Bonzini     err_new->err_class = err->err_class;
121baacf047SPaolo Bonzini 
122baacf047SPaolo Bonzini     return err_new;
123baacf047SPaolo Bonzini }
124baacf047SPaolo Bonzini 
125baacf047SPaolo Bonzini bool error_is_set(Error **errp)
126baacf047SPaolo Bonzini {
127baacf047SPaolo Bonzini     return (errp && *errp);
128baacf047SPaolo Bonzini }
129baacf047SPaolo Bonzini 
130baacf047SPaolo Bonzini ErrorClass error_get_class(const Error *err)
131baacf047SPaolo Bonzini {
132baacf047SPaolo Bonzini     return err->err_class;
133baacf047SPaolo Bonzini }
134baacf047SPaolo Bonzini 
135baacf047SPaolo Bonzini const char *error_get_pretty(Error *err)
136baacf047SPaolo Bonzini {
137baacf047SPaolo Bonzini     return err->msg;
138baacf047SPaolo Bonzini }
139baacf047SPaolo Bonzini 
140baacf047SPaolo Bonzini void error_free(Error *err)
141baacf047SPaolo Bonzini {
142baacf047SPaolo Bonzini     if (err) {
143baacf047SPaolo Bonzini         g_free(err->msg);
144baacf047SPaolo Bonzini         g_free(err);
145baacf047SPaolo Bonzini     }
146baacf047SPaolo Bonzini }
147baacf047SPaolo Bonzini 
148baacf047SPaolo Bonzini void error_propagate(Error **dst_err, Error *local_err)
149baacf047SPaolo Bonzini {
150baacf047SPaolo Bonzini     if (dst_err && !*dst_err) {
151baacf047SPaolo Bonzini         *dst_err = local_err;
152baacf047SPaolo Bonzini     } else if (local_err) {
153baacf047SPaolo Bonzini         error_free(local_err);
154baacf047SPaolo Bonzini     }
155baacf047SPaolo Bonzini }
156