2
0

error.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*
  2. * QEMU Error Objects
  3. *
  4. * Copyright IBM, Corp. 2011
  5. * Copyright (C) 2011-2015 Red Hat, Inc.
  6. *
  7. * Authors:
  8. * Anthony Liguori <aliguori@us.ibm.com>
  9. * Markus Armbruster <armbru@redhat.com>,
  10. *
  11. * This work is licensed under the terms of the GNU LGPL, version 2. See
  12. * the COPYING.LIB file in the top-level directory.
  13. */
  14. #include "qemu/osdep.h"
  15. #include "qapi/error.h"
  16. #include "qemu/error-report.h"
  17. struct Error
  18. {
  19. char *msg;
  20. ErrorClass err_class;
  21. const char *src, *func;
  22. int line;
  23. GString *hint;
  24. };
  25. Error *error_abort;
  26. Error *error_fatal;
  27. static void error_handle_fatal(Error **errp, Error *err)
  28. {
  29. if (errp == &error_abort) {
  30. fprintf(stderr, "Unexpected error in %s() at %s:%d:\n",
  31. err->func, err->src, err->line);
  32. error_report("%s", error_get_pretty(err));
  33. if (err->hint) {
  34. error_printf("%s", err->hint->str);
  35. }
  36. abort();
  37. }
  38. if (errp == &error_fatal) {
  39. error_report_err(err);
  40. exit(1);
  41. }
  42. }
  43. static void error_setv(Error **errp,
  44. const char *src, int line, const char *func,
  45. ErrorClass err_class, const char *fmt, va_list ap,
  46. const char *suffix)
  47. {
  48. Error *err;
  49. int saved_errno = errno;
  50. if (errp == NULL) {
  51. return;
  52. }
  53. assert(*errp == NULL);
  54. err = g_malloc0(sizeof(*err));
  55. err->msg = g_strdup_vprintf(fmt, ap);
  56. if (suffix) {
  57. char *msg = err->msg;
  58. err->msg = g_strdup_printf("%s: %s", msg, suffix);
  59. g_free(msg);
  60. }
  61. err->err_class = err_class;
  62. err->src = src;
  63. err->line = line;
  64. err->func = func;
  65. error_handle_fatal(errp, err);
  66. *errp = err;
  67. errno = saved_errno;
  68. }
  69. void error_set_internal(Error **errp,
  70. const char *src, int line, const char *func,
  71. ErrorClass err_class, const char *fmt, ...)
  72. {
  73. va_list ap;
  74. va_start(ap, fmt);
  75. error_setv(errp, src, line, func, err_class, fmt, ap, NULL);
  76. va_end(ap);
  77. }
  78. void error_setg_internal(Error **errp,
  79. const char *src, int line, const char *func,
  80. const char *fmt, ...)
  81. {
  82. va_list ap;
  83. va_start(ap, fmt);
  84. error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap, NULL);
  85. va_end(ap);
  86. }
  87. void error_setg_errno_internal(Error **errp,
  88. const char *src, int line, const char *func,
  89. int os_errno, const char *fmt, ...)
  90. {
  91. va_list ap;
  92. int saved_errno = errno;
  93. va_start(ap, fmt);
  94. error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap,
  95. os_errno != 0 ? strerror(os_errno) : NULL);
  96. va_end(ap);
  97. errno = saved_errno;
  98. }
  99. void error_setg_file_open_internal(Error **errp,
  100. const char *src, int line, const char *func,
  101. int os_errno, const char *filename)
  102. {
  103. error_setg_errno_internal(errp, src, line, func, os_errno,
  104. "Could not open '%s'", filename);
  105. }
  106. void error_vprepend(Error **errp, const char *fmt, va_list ap)
  107. {
  108. GString *newmsg;
  109. if (!errp) {
  110. return;
  111. }
  112. newmsg = g_string_new(NULL);
  113. g_string_vprintf(newmsg, fmt, ap);
  114. g_string_append(newmsg, (*errp)->msg);
  115. g_free((*errp)->msg);
  116. (*errp)->msg = g_string_free(newmsg, 0);
  117. }
  118. void error_prepend(Error **errp, const char *fmt, ...)
  119. {
  120. va_list ap;
  121. va_start(ap, fmt);
  122. error_vprepend(errp, fmt, ap);
  123. va_end(ap);
  124. }
  125. void error_append_hint(Error **errp, const char *fmt, ...)
  126. {
  127. va_list ap;
  128. int saved_errno = errno;
  129. Error *err;
  130. if (!errp) {
  131. return;
  132. }
  133. err = *errp;
  134. assert(err && errp != &error_abort && errp != &error_fatal);
  135. if (!err->hint) {
  136. err->hint = g_string_new(NULL);
  137. }
  138. va_start(ap, fmt);
  139. g_string_append_vprintf(err->hint, fmt, ap);
  140. va_end(ap);
  141. errno = saved_errno;
  142. }
  143. #ifdef _WIN32
  144. void error_setg_win32_internal(Error **errp,
  145. const char *src, int line, const char *func,
  146. int win32_err, const char *fmt, ...)
  147. {
  148. va_list ap;
  149. char *suffix = NULL;
  150. if (errp == NULL) {
  151. return;
  152. }
  153. if (win32_err != 0) {
  154. suffix = g_win32_error_message(win32_err);
  155. }
  156. va_start(ap, fmt);
  157. error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR,
  158. fmt, ap, suffix);
  159. va_end(ap);
  160. g_free(suffix);
  161. }
  162. #endif
  163. Error *error_copy(const Error *err)
  164. {
  165. Error *err_new;
  166. err_new = g_malloc0(sizeof(*err));
  167. err_new->msg = g_strdup(err->msg);
  168. err_new->err_class = err->err_class;
  169. err_new->src = err->src;
  170. err_new->line = err->line;
  171. err_new->func = err->func;
  172. if (err->hint) {
  173. err_new->hint = g_string_new(err->hint->str);
  174. }
  175. return err_new;
  176. }
  177. ErrorClass error_get_class(const Error *err)
  178. {
  179. return err->err_class;
  180. }
  181. const char *error_get_pretty(const Error *err)
  182. {
  183. return err->msg;
  184. }
  185. void error_report_err(Error *err)
  186. {
  187. error_report("%s", error_get_pretty(err));
  188. if (err->hint) {
  189. error_printf("%s", err->hint->str);
  190. }
  191. error_free(err);
  192. }
  193. void warn_report_err(Error *err)
  194. {
  195. warn_report("%s", error_get_pretty(err));
  196. if (err->hint) {
  197. error_printf("%s", err->hint->str);
  198. }
  199. error_free(err);
  200. }
  201. void error_reportf_err(Error *err, const char *fmt, ...)
  202. {
  203. va_list ap;
  204. va_start(ap, fmt);
  205. error_vprepend(&err, fmt, ap);
  206. va_end(ap);
  207. error_report_err(err);
  208. }
  209. void warn_reportf_err(Error *err, const char *fmt, ...)
  210. {
  211. va_list ap;
  212. va_start(ap, fmt);
  213. error_vprepend(&err, fmt, ap);
  214. va_end(ap);
  215. warn_report_err(err);
  216. }
  217. void error_free(Error *err)
  218. {
  219. if (err) {
  220. g_free(err->msg);
  221. if (err->hint) {
  222. g_string_free(err->hint, true);
  223. }
  224. g_free(err);
  225. }
  226. }
  227. void error_free_or_abort(Error **errp)
  228. {
  229. assert(errp && *errp);
  230. error_free(*errp);
  231. *errp = NULL;
  232. }
  233. void error_propagate(Error **dst_errp, Error *local_err)
  234. {
  235. if (!local_err) {
  236. return;
  237. }
  238. error_handle_fatal(dst_errp, local_err);
  239. if (dst_errp && !*dst_errp) {
  240. *dst_errp = local_err;
  241. } else {
  242. error_free(local_err);
  243. }
  244. }
  245. void error_propagate_prepend(Error **dst_errp, Error *err,
  246. const char *fmt, ...)
  247. {
  248. va_list ap;
  249. if (dst_errp && !*dst_errp) {
  250. va_start(ap, fmt);
  251. error_vprepend(&err, fmt, ap);
  252. va_end(ap);
  253. } /* else error is being ignored, don't bother with prepending */
  254. error_propagate(dst_errp, err);
  255. }