]> git.proxmox.com Git - mirror_qemu.git/blame - util/error.c
error: only prepend timestamp on stderr
[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;
1e9b65bb
MA
21 const char *src, *func;
22 int line;
d5ec4f27
LC
23};
24
5d24ee70
PC
25Error *error_abort;
26
1e9b65bb
MA
27static void error_do_abort(Error *err)
28{
29 fprintf(stderr, "Unexpected error in %s() at %s:%d:\n",
30 err->func, err->src, err->line);
31 error_report_err(err);
32 abort();
33}
34
35static void error_setv(Error **errp,
36 const char *src, int line, const char *func,
37 ErrorClass err_class, const char *fmt, va_list ap)
d5ec4f27
LC
38{
39 Error *err;
b276d249 40 int saved_errno = errno;
d5ec4f27
LC
41
42 if (errp == NULL) {
43 return;
44 }
d195325b 45 assert(*errp == NULL);
d5ec4f27 46
7267c094 47 err = g_malloc0(sizeof(*err));
df1e608a 48 err->msg = g_strdup_vprintf(fmt, ap);
13f59ae8 49 err->err_class = err_class;
1e9b65bb
MA
50 err->src = src;
51 err->line = line;
52 err->func = func;
d5ec4f27 53
5d24ee70 54 if (errp == &error_abort) {
1e9b65bb 55 error_do_abort(err);
5d24ee70
PC
56 }
57
d5ec4f27 58 *errp = err;
b276d249
HR
59
60 errno = saved_errno;
d5ec4f27
LC
61}
62
1e9b65bb
MA
63void error_set_internal(Error **errp,
64 const char *src, int line, const char *func,
65 ErrorClass err_class, const char *fmt, ...)
55237508
MA
66{
67 va_list ap;
68
69 va_start(ap, fmt);
1e9b65bb 70 error_setv(errp, src, line, func, err_class, fmt, ap);
55237508
MA
71 va_end(ap);
72}
73
1e9b65bb
MA
74void error_setg_internal(Error **errp,
75 const char *src, int line, const char *func,
76 const char *fmt, ...)
a9499ddd
MA
77{
78 va_list ap;
79
80 va_start(ap, fmt);
1e9b65bb 81 error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap);
a9499ddd
MA
82 va_end(ap);
83}
84
1e9b65bb
MA
85void error_setg_errno_internal(Error **errp,
86 const char *src, int line, const char *func,
87 int os_errno, const char *fmt, ...)
680d16dc 88{
680d16dc 89 va_list ap;
55237508 90 char *msg;
b276d249 91 int saved_errno = errno;
680d16dc
PB
92
93 if (errp == NULL) {
94 return;
95 }
680d16dc
PB
96
97 va_start(ap, fmt);
1e9b65bb 98 error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap);
680d16dc 99 va_end(ap);
680d16dc 100
55237508
MA
101 if (os_errno != 0) {
102 msg = (*errp)->msg;
103 (*errp)->msg = g_strdup_printf("%s: %s", msg, strerror(os_errno));
104 g_free(msg);
5d24ee70
PC
105 }
106
b276d249 107 errno = saved_errno;
680d16dc
PB
108}
109
1e9b65bb
MA
110void error_setg_file_open_internal(Error **errp,
111 const char *src, int line, const char *func,
112 int os_errno, const char *filename)
54028d75 113{
1e9b65bb
MA
114 error_setg_errno_internal(errp, src, line, func, os_errno,
115 "Could not open '%s'", filename);
54028d75
LC
116}
117
20840d4c
TS
118#ifdef _WIN32
119
1e9b65bb
MA
120void error_setg_win32_internal(Error **errp,
121 const char *src, int line, const char *func,
122 int win32_err, const char *fmt, ...)
20840d4c 123{
20840d4c 124 va_list ap;
55237508 125 char *msg1, *msg2;
20840d4c
TS
126
127 if (errp == NULL) {
128 return;
129 }
20840d4c
TS
130
131 va_start(ap, fmt);
1e9b65bb 132 error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap);
55237508
MA
133 va_end(ap);
134
20840d4c 135 if (win32_err != 0) {
55237508
MA
136 msg1 = (*errp)->msg;
137 msg2 = g_win32_error_message(win32_err);
138 (*errp)->msg = g_strdup_printf("%s: %s (error: %x)", msg1, msg2,
139 (unsigned)win32_err);
20840d4c
TS
140 g_free(msg2);
141 g_free(msg1);
5d24ee70 142 }
20840d4c
TS
143}
144
145#endif
146
79020cfc
LC
147Error *error_copy(const Error *err)
148{
149 Error *err_new;
150
151 err_new = g_malloc0(sizeof(*err));
152 err_new->msg = g_strdup(err->msg);
13f59ae8 153 err_new->err_class = err->err_class;
79020cfc
LC
154
155 return err_new;
156}
157
ea25fbca
LC
158ErrorClass error_get_class(const Error *err)
159{
160 return err->err_class;
161}
162
d5ec4f27
LC
163const char *error_get_pretty(Error *err)
164{
d5ec4f27
LC
165 return err->msg;
166}
167
2ee2f1e4
MA
168void error_report_err(Error *err)
169{
170 error_report("%s", error_get_pretty(err));
171 error_free(err);
172}
173
d5ec4f27
LC
174void error_free(Error *err)
175{
176 if (err) {
7267c094
AL
177 g_free(err->msg);
178 g_free(err);
d5ec4f27
LC
179 }
180}
181
64dfefed 182void error_propagate(Error **dst_errp, Error *local_err)
d5ec4f27 183{
64dfefed 184 if (local_err && dst_errp == &error_abort) {
1e9b65bb 185 error_do_abort(local_err);
64dfefed
MA
186 } else if (dst_errp && !*dst_errp) {
187 *dst_errp = local_err;
d5ec4f27
LC
188 } else if (local_err) {
189 error_free(local_err);
190 }
191}