maint: remove unused include for strings.h
[qemu/ar7.git] / util / error.c
blobcdb726ce813e4eca006067620326682028e7846b
1 /*
2 * QEMU Error Objects
4 * Copyright IBM, Corp. 2011
6 * Authors:
7 * Anthony Liguori <aliguori@us.ibm.com>
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.
13 #include "qemu-common.h"
14 #include "qapi/error.h"
15 #include "qemu/error-report.h"
17 struct Error
19 char *msg;
20 ErrorClass err_class;
21 const char *src, *func;
22 int line;
25 Error *error_abort;
27 static void error_do_abort(Error *err)
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();
35 static void error_setv(Error **errp,
36 const char *src, int line, const char *func,
37 ErrorClass err_class, const char *fmt, va_list ap)
39 Error *err;
40 int saved_errno = errno;
42 if (errp == NULL) {
43 return;
45 assert(*errp == NULL);
47 err = g_malloc0(sizeof(*err));
48 err->msg = g_strdup_vprintf(fmt, ap);
49 err->err_class = err_class;
50 err->src = src;
51 err->line = line;
52 err->func = func;
54 if (errp == &error_abort) {
55 error_do_abort(err);
58 *errp = err;
60 errno = saved_errno;
63 void error_set_internal(Error **errp,
64 const char *src, int line, const char *func,
65 ErrorClass err_class, const char *fmt, ...)
67 va_list ap;
69 va_start(ap, fmt);
70 error_setv(errp, src, line, func, err_class, fmt, ap);
71 va_end(ap);
74 void error_setg_internal(Error **errp,
75 const char *src, int line, const char *func,
76 const char *fmt, ...)
78 va_list ap;
80 va_start(ap, fmt);
81 error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap);
82 va_end(ap);
85 void error_setg_errno_internal(Error **errp,
86 const char *src, int line, const char *func,
87 int os_errno, const char *fmt, ...)
89 va_list ap;
90 char *msg;
91 int saved_errno = errno;
93 if (errp == NULL) {
94 return;
97 va_start(ap, fmt);
98 error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap);
99 va_end(ap);
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);
107 errno = saved_errno;
110 void error_setg_file_open_internal(Error **errp,
111 const char *src, int line, const char *func,
112 int os_errno, const char *filename)
114 error_setg_errno_internal(errp, src, line, func, os_errno,
115 "Could not open '%s'", filename);
118 #ifdef _WIN32
120 void error_setg_win32_internal(Error **errp,
121 const char *src, int line, const char *func,
122 int win32_err, const char *fmt, ...)
124 va_list ap;
125 char *msg1, *msg2;
127 if (errp == NULL) {
128 return;
131 va_start(ap, fmt);
132 error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap);
133 va_end(ap);
135 if (win32_err != 0) {
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);
140 g_free(msg2);
141 g_free(msg1);
145 #endif
147 Error *error_copy(const Error *err)
149 Error *err_new;
151 err_new = g_malloc0(sizeof(*err));
152 err_new->msg = g_strdup(err->msg);
153 err_new->err_class = err->err_class;
155 return err_new;
158 ErrorClass error_get_class(const Error *err)
160 return err->err_class;
163 const char *error_get_pretty(Error *err)
165 return err->msg;
168 void error_report_err(Error *err)
170 error_report("%s", error_get_pretty(err));
171 error_free(err);
174 void error_free(Error *err)
176 if (err) {
177 g_free(err->msg);
178 g_free(err);
182 void error_propagate(Error **dst_errp, Error *local_err)
184 if (local_err && dst_errp == &error_abort) {
185 error_do_abort(local_err);
186 } else if (dst_errp && !*dst_errp) {
187 *dst_errp = local_err;
188 } else if (local_err) {
189 error_free(local_err);