]> git.proxmox.com Git - mirror_qemu.git/blame - util/error.c
error: Revamp interface documentation
[mirror_qemu.git] / util / error.c
CommitLineData
d5ec4f27
LC
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 */
e4ea5e2d
SW
12
13#include "qemu-common.h"
7b1b5d19 14#include "qapi/error.h"
073a3411 15#include "qemu/error-report.h"
d5ec4f27
LC
16
17struct Error
18{
d5ec4f27 19 char *msg;
13f59ae8 20 ErrorClass err_class;
d5ec4f27
LC
21};
22
5d24ee70
PC
23Error *error_abort;
24
55237508
MA
25static void error_setv(Error **errp, ErrorClass err_class,
26 const char *fmt, va_list ap)
d5ec4f27
LC
27{
28 Error *err;
b276d249 29 int saved_errno = errno;
d5ec4f27
LC
30
31 if (errp == NULL) {
32 return;
33 }
d195325b 34 assert(*errp == NULL);
d5ec4f27 35
7267c094 36 err = g_malloc0(sizeof(*err));
df1e608a 37 err->msg = g_strdup_vprintf(fmt, ap);
13f59ae8 38 err->err_class = err_class;
d5ec4f27 39
5d24ee70 40 if (errp == &error_abort) {
565f65d2 41 error_report_err(err);
5d24ee70
PC
42 abort();
43 }
44
d5ec4f27 45 *errp = err;
b276d249
HR
46
47 errno = saved_errno;
d5ec4f27
LC
48}
49
55237508
MA
50void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
51{
52 va_list ap;
53
54 va_start(ap, fmt);
55 error_setv(errp, err_class, fmt, ap);
56 va_end(ap);
57}
58
a9499ddd
MA
59void error_setg(Error **errp, const char *fmt, ...)
60{
61 va_list ap;
62
63 va_start(ap, fmt);
64 error_setv(errp, ERROR_CLASS_GENERIC_ERROR, fmt, ap);
65 va_end(ap);
66}
67
4463dcb8 68void error_setg_errno(Error **errp, int os_errno, const char *fmt, ...)
680d16dc 69{
680d16dc 70 va_list ap;
55237508 71 char *msg;
b276d249 72 int saved_errno = errno;
680d16dc
PB
73
74 if (errp == NULL) {
75 return;
76 }
680d16dc
PB
77
78 va_start(ap, fmt);
4463dcb8 79 error_setv(errp, ERROR_CLASS_GENERIC_ERROR, fmt, ap);
680d16dc 80 va_end(ap);
680d16dc 81
55237508
MA
82 if (os_errno != 0) {
83 msg = (*errp)->msg;
84 (*errp)->msg = g_strdup_printf("%s: %s", msg, strerror(os_errno));
85 g_free(msg);
5d24ee70
PC
86 }
87
b276d249 88 errno = saved_errno;
680d16dc
PB
89}
90
54028d75
LC
91void error_setg_file_open(Error **errp, int os_errno, const char *filename)
92{
93 error_setg_errno(errp, os_errno, "Could not open '%s'", filename);
94}
95
20840d4c
TS
96#ifdef _WIN32
97
e7cf59e8 98void error_setg_win32(Error **errp, int win32_err, const char *fmt, ...)
20840d4c 99{
20840d4c 100 va_list ap;
55237508 101 char *msg1, *msg2;
20840d4c
TS
102
103 if (errp == NULL) {
104 return;
105 }
20840d4c
TS
106
107 va_start(ap, fmt);
e7cf59e8 108 error_setv(errp, ERROR_CLASS_GENERIC_ERROR, fmt, ap);
55237508
MA
109 va_end(ap);
110
20840d4c 111 if (win32_err != 0) {
55237508
MA
112 msg1 = (*errp)->msg;
113 msg2 = g_win32_error_message(win32_err);
114 (*errp)->msg = g_strdup_printf("%s: %s (error: %x)", msg1, msg2,
115 (unsigned)win32_err);
20840d4c
TS
116 g_free(msg2);
117 g_free(msg1);
5d24ee70 118 }
20840d4c
TS
119}
120
121#endif
122
79020cfc
LC
123Error *error_copy(const Error *err)
124{
125 Error *err_new;
126
127 err_new = g_malloc0(sizeof(*err));
128 err_new->msg = g_strdup(err->msg);
13f59ae8 129 err_new->err_class = err->err_class;
79020cfc
LC
130
131 return err_new;
132}
133
ea25fbca
LC
134ErrorClass error_get_class(const Error *err)
135{
136 return err->err_class;
137}
138
d5ec4f27
LC
139const char *error_get_pretty(Error *err)
140{
d5ec4f27
LC
141 return err->msg;
142}
143
2ee2f1e4
MA
144void error_report_err(Error *err)
145{
146 error_report("%s", error_get_pretty(err));
147 error_free(err);
148}
149
d5ec4f27
LC
150void error_free(Error *err)
151{
152 if (err) {
7267c094
AL
153 g_free(err->msg);
154 g_free(err);
d5ec4f27
LC
155 }
156}
157
64dfefed 158void error_propagate(Error **dst_errp, Error *local_err)
d5ec4f27 159{
64dfefed 160 if (local_err && dst_errp == &error_abort) {
565f65d2 161 error_report_err(local_err);
5d24ee70 162 abort();
64dfefed
MA
163 } else if (dst_errp && !*dst_errp) {
164 *dst_errp = local_err;
d5ec4f27
LC
165 } else if (local_err) {
166 error_free(local_err);
167 }
168}