2
0

error.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. */
  12. #include "qemu-common.h"
  13. #include "error.h"
  14. #include "qjson.h"
  15. #include "qdict.h"
  16. #include "error_int.h"
  17. #include "qerror.h"
  18. struct Error
  19. {
  20. QDict *obj;
  21. const char *fmt;
  22. char *msg;
  23. };
  24. void error_set(Error **errp, const char *fmt, ...)
  25. {
  26. Error *err;
  27. va_list ap;
  28. if (errp == NULL) {
  29. return;
  30. }
  31. err = g_malloc0(sizeof(*err));
  32. va_start(ap, fmt);
  33. err->obj = qobject_to_qdict(qobject_from_jsonv(fmt, &ap));
  34. va_end(ap);
  35. err->fmt = fmt;
  36. *errp = err;
  37. }
  38. Error *error_copy(const Error *err)
  39. {
  40. Error *err_new;
  41. err_new = g_malloc0(sizeof(*err));
  42. err_new->msg = g_strdup(err->msg);
  43. err_new->fmt = err->fmt;
  44. err_new->obj = err->obj;
  45. QINCREF(err_new->obj);
  46. return err_new;
  47. }
  48. bool error_is_set(Error **errp)
  49. {
  50. return (errp && *errp);
  51. }
  52. const char *error_get_pretty(Error *err)
  53. {
  54. if (err->msg == NULL) {
  55. QString *str;
  56. str = qerror_format(err->fmt, err->obj);
  57. err->msg = g_strdup(qstring_get_str(str));
  58. QDECREF(str);
  59. }
  60. return err->msg;
  61. }
  62. const char *error_get_field(Error *err, const char *field)
  63. {
  64. if (strcmp(field, "class") == 0) {
  65. return qdict_get_str(err->obj, field);
  66. } else {
  67. QDict *dict = qdict_get_qdict(err->obj, "data");
  68. return qdict_get_str(dict, field);
  69. }
  70. }
  71. QDict *error_get_data(Error *err)
  72. {
  73. QDict *data = qdict_get_qdict(err->obj, "data");
  74. QINCREF(data);
  75. return data;
  76. }
  77. void error_set_field(Error *err, const char *field, const char *value)
  78. {
  79. QDict *dict = qdict_get_qdict(err->obj, "data");
  80. qdict_put(dict, field, qstring_from_str(value));
  81. }
  82. void error_free(Error *err)
  83. {
  84. if (err) {
  85. QDECREF(err->obj);
  86. g_free(err->msg);
  87. g_free(err);
  88. }
  89. }
  90. bool error_is_type(Error *err, const char *fmt)
  91. {
  92. const char *error_class;
  93. char *ptr;
  94. char *end;
  95. if (!err) {
  96. return false;
  97. }
  98. ptr = strstr(fmt, "'class': '");
  99. assert(ptr != NULL);
  100. ptr += strlen("'class': '");
  101. end = strchr(ptr, '\'');
  102. assert(end != NULL);
  103. error_class = error_get_field(err, "class");
  104. if (strlen(error_class) != end - ptr) {
  105. return false;
  106. }
  107. return strncmp(ptr, error_class, end - ptr) == 0;
  108. }
  109. void error_propagate(Error **dst_err, Error *local_err)
  110. {
  111. if (dst_err) {
  112. *dst_err = local_err;
  113. } else if (local_err) {
  114. error_free(local_err);
  115. }
  116. }
  117. QObject *error_get_qobject(Error *err)
  118. {
  119. QINCREF(err->obj);
  120. return QOBJECT(err->obj);
  121. }
  122. void error_set_qobject(Error **errp, QObject *obj)
  123. {
  124. Error *err;
  125. if (errp == NULL) {
  126. return;
  127. }
  128. err = g_malloc0(sizeof(*err));
  129. err->obj = qobject_to_qdict(obj);
  130. qobject_incref(obj);
  131. *errp = err;
  132. }