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