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