2
0

error.c 2.7 KB

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