1 /* 2 * QError Module 3 * 4 * Copyright (C) 2009 Red Hat Inc. 5 * 6 * Authors: 7 * Luiz Capitulino <lcapitulino (at) redhat.com> 8 * 9 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. 10 * See the COPYING.LIB file in the top-level directory. 11 */ 12 13 #include "monitor/monitor.h" 14 #include "qapi/qmp/qjson.h" 15 #include "qapi/qmp/qerror.h" 16 #include "qemu-common.h" 17 18 static void qerror_destroy_obj(QObject *obj); 19 20 static const QType qerror_type = { 21 .code = QTYPE_QERROR, 22 .destroy = qerror_destroy_obj, 23 }; 24 25 /** 26 * qerror_new(): Create a new QError 27 * 28 * Return strong reference. 29 */ 30 static QError *qerror_new(void) 31 { 32 QError *qerr; 33 34 qerr = g_malloc0(sizeof(*qerr)); 35 QOBJECT_INIT(qerr, &qerror_type); 36 37 return qerr; 38 } 39 40 /** 41 * qerror_from_info(): Create a new QError from error information 42 * 43 * Return strong reference. 44 */ 45 static QError * GCC_FMT_ATTR(2, 0) 46 qerror_from_info(ErrorClass err_class, const char *fmt, va_list *va) 47 { 48 QError *qerr; 49 50 qerr = qerror_new(); 51 loc_save(&qerr->loc); 52 53 qerr->err_msg = g_strdup_vprintf(fmt, *va); 54 qerr->err_class = err_class; 55 56 return qerr; 57 } 58 59 /** 60 * qerror_human(): Format QError data into human-readable string. 61 */ 62 QString *qerror_human(const QError *qerror) 63 { 64 return qstring_from_str(qerror->err_msg); 65 } 66 67 /** 68 * qerror_print(): Print QError data 69 * 70 * This function will print the member 'desc' of the specified QError object, 71 * it uses error_report() for this, so that the output is routed to the right 72 * place (ie. stderr or Monitor's device). 73 */ 74 static void qerror_print(QError *qerror) 75 { 76 QString *qstring = qerror_human(qerror); 77 loc_push_restore(&qerror->loc); 78 error_report("%s", qstring_get_str(qstring)); 79 loc_pop(&qerror->loc); 80 QDECREF(qstring); 81 } 82 83 void qerror_report(ErrorClass eclass, const char *fmt, ...) 84 { 85 va_list va; 86 QError *qerror; 87 88 va_start(va, fmt); 89 qerror = qerror_from_info(eclass, fmt, &va); 90 va_end(va); 91 92 if (monitor_cur_is_qmp()) { 93 monitor_set_error(cur_mon, qerror); 94 } else { 95 qerror_print(qerror); 96 QDECREF(qerror); 97 } 98 } 99 100 /* Evil... */ 101 struct Error 102 { 103 char *msg; 104 ErrorClass err_class; 105 }; 106 107 void qerror_report_err(Error *err) 108 { 109 QError *qerr; 110 111 qerr = qerror_new(); 112 loc_save(&qerr->loc); 113 qerr->err_msg = g_strdup(err->msg); 114 qerr->err_class = err->err_class; 115 116 if (monitor_cur_is_qmp()) { 117 monitor_set_error(cur_mon, qerr); 118 } else { 119 qerror_print(qerr); 120 QDECREF(qerr); 121 } 122 } 123 124 void assert_no_error(Error *err) 125 { 126 if (err) { 127 qerror_report_err(err); 128 abort(); 129 } 130 } 131 132 /** 133 * qobject_to_qerror(): Convert a QObject into a QError 134 */ 135 static QError *qobject_to_qerror(const QObject *obj) 136 { 137 if (qobject_type(obj) != QTYPE_QERROR) { 138 return NULL; 139 } 140 141 return container_of(obj, QError, base); 142 } 143 144 /** 145 * qerror_destroy_obj(): Free all memory allocated by a QError 146 */ 147 static void qerror_destroy_obj(QObject *obj) 148 { 149 QError *qerr; 150 151 assert(obj != NULL); 152 qerr = qobject_to_qerror(obj); 153 154 g_free(qerr->err_msg); 155 g_free(qerr); 156 } 157