1baacf047SPaolo Bonzini /* 2baacf047SPaolo Bonzini * QEMU Error Objects 3baacf047SPaolo Bonzini * 4baacf047SPaolo Bonzini * Copyright IBM, Corp. 2011 5baacf047SPaolo Bonzini * 6baacf047SPaolo Bonzini * Authors: 7baacf047SPaolo Bonzini * Anthony Liguori <aliguori@us.ibm.com> 8baacf047SPaolo Bonzini * 9baacf047SPaolo Bonzini * This work is licensed under the terms of the GNU LGPL, version 2. See 10baacf047SPaolo Bonzini * the COPYING.LIB file in the top-level directory. 11baacf047SPaolo Bonzini */ 12baacf047SPaolo Bonzini 13baacf047SPaolo Bonzini #include "qemu-common.h" 14baacf047SPaolo Bonzini #include "qapi/error.h" 15073a3411SCole Robinson #include "qemu/error-report.h" 16baacf047SPaolo Bonzini 17baacf047SPaolo Bonzini struct Error 18baacf047SPaolo Bonzini { 19baacf047SPaolo Bonzini char *msg; 20baacf047SPaolo Bonzini ErrorClass err_class; 21*1e9b65bbSMarkus Armbruster const char *src, *func; 22*1e9b65bbSMarkus Armbruster int line; 23baacf047SPaolo Bonzini }; 24baacf047SPaolo Bonzini 255d24ee70SPeter Crosthwaite Error *error_abort; 265d24ee70SPeter Crosthwaite 27*1e9b65bbSMarkus Armbruster static void error_do_abort(Error *err) 28*1e9b65bbSMarkus Armbruster { 29*1e9b65bbSMarkus Armbruster fprintf(stderr, "Unexpected error in %s() at %s:%d:\n", 30*1e9b65bbSMarkus Armbruster err->func, err->src, err->line); 31*1e9b65bbSMarkus Armbruster error_report_err(err); 32*1e9b65bbSMarkus Armbruster abort(); 33*1e9b65bbSMarkus Armbruster } 34*1e9b65bbSMarkus Armbruster 35*1e9b65bbSMarkus Armbruster static void error_setv(Error **errp, 36*1e9b65bbSMarkus Armbruster const char *src, int line, const char *func, 37*1e9b65bbSMarkus Armbruster ErrorClass err_class, const char *fmt, va_list ap) 38baacf047SPaolo Bonzini { 39baacf047SPaolo Bonzini Error *err; 40b276d249SMax Reitz int saved_errno = errno; 41baacf047SPaolo Bonzini 42baacf047SPaolo Bonzini if (errp == NULL) { 43baacf047SPaolo Bonzini return; 44baacf047SPaolo Bonzini } 45baacf047SPaolo Bonzini assert(*errp == NULL); 46baacf047SPaolo Bonzini 47baacf047SPaolo Bonzini err = g_malloc0(sizeof(*err)); 48baacf047SPaolo Bonzini err->msg = g_strdup_vprintf(fmt, ap); 49baacf047SPaolo Bonzini err->err_class = err_class; 50*1e9b65bbSMarkus Armbruster err->src = src; 51*1e9b65bbSMarkus Armbruster err->line = line; 52*1e9b65bbSMarkus Armbruster err->func = func; 53baacf047SPaolo Bonzini 545d24ee70SPeter Crosthwaite if (errp == &error_abort) { 55*1e9b65bbSMarkus Armbruster error_do_abort(err); 565d24ee70SPeter Crosthwaite } 575d24ee70SPeter Crosthwaite 58baacf047SPaolo Bonzini *errp = err; 59b276d249SMax Reitz 60b276d249SMax Reitz errno = saved_errno; 61baacf047SPaolo Bonzini } 62baacf047SPaolo Bonzini 63*1e9b65bbSMarkus Armbruster void error_set_internal(Error **errp, 64*1e9b65bbSMarkus Armbruster const char *src, int line, const char *func, 65*1e9b65bbSMarkus Armbruster ErrorClass err_class, const char *fmt, ...) 6655237508SMarkus Armbruster { 6755237508SMarkus Armbruster va_list ap; 6855237508SMarkus Armbruster 6955237508SMarkus Armbruster va_start(ap, fmt); 70*1e9b65bbSMarkus Armbruster error_setv(errp, src, line, func, err_class, fmt, ap); 7155237508SMarkus Armbruster va_end(ap); 7255237508SMarkus Armbruster } 7355237508SMarkus Armbruster 74*1e9b65bbSMarkus Armbruster void error_setg_internal(Error **errp, 75*1e9b65bbSMarkus Armbruster const char *src, int line, const char *func, 76*1e9b65bbSMarkus Armbruster const char *fmt, ...) 77a9499dddSMarkus Armbruster { 78a9499dddSMarkus Armbruster va_list ap; 79a9499dddSMarkus Armbruster 80a9499dddSMarkus Armbruster va_start(ap, fmt); 81*1e9b65bbSMarkus Armbruster error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap); 82a9499dddSMarkus Armbruster va_end(ap); 83a9499dddSMarkus Armbruster } 84a9499dddSMarkus Armbruster 85*1e9b65bbSMarkus Armbruster void error_setg_errno_internal(Error **errp, 86*1e9b65bbSMarkus Armbruster const char *src, int line, const char *func, 87*1e9b65bbSMarkus Armbruster int os_errno, const char *fmt, ...) 88baacf047SPaolo Bonzini { 89baacf047SPaolo Bonzini va_list ap; 9055237508SMarkus Armbruster char *msg; 91b276d249SMax Reitz int saved_errno = errno; 92baacf047SPaolo Bonzini 93baacf047SPaolo Bonzini if (errp == NULL) { 94baacf047SPaolo Bonzini return; 95baacf047SPaolo Bonzini } 96baacf047SPaolo Bonzini 97baacf047SPaolo Bonzini va_start(ap, fmt); 98*1e9b65bbSMarkus Armbruster error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap); 99baacf047SPaolo Bonzini va_end(ap); 100baacf047SPaolo Bonzini 10155237508SMarkus Armbruster if (os_errno != 0) { 10255237508SMarkus Armbruster msg = (*errp)->msg; 10355237508SMarkus Armbruster (*errp)->msg = g_strdup_printf("%s: %s", msg, strerror(os_errno)); 10455237508SMarkus Armbruster g_free(msg); 1055d24ee70SPeter Crosthwaite } 1065d24ee70SPeter Crosthwaite 107b276d249SMax Reitz errno = saved_errno; 108baacf047SPaolo Bonzini } 109baacf047SPaolo Bonzini 110*1e9b65bbSMarkus Armbruster void error_setg_file_open_internal(Error **errp, 111*1e9b65bbSMarkus Armbruster const char *src, int line, const char *func, 112*1e9b65bbSMarkus Armbruster int os_errno, const char *filename) 11354028d75SLuiz Capitulino { 114*1e9b65bbSMarkus Armbruster error_setg_errno_internal(errp, src, line, func, os_errno, 115*1e9b65bbSMarkus Armbruster "Could not open '%s'", filename); 11654028d75SLuiz Capitulino } 11754028d75SLuiz Capitulino 11820840d4cSTomoki Sekiyama #ifdef _WIN32 11920840d4cSTomoki Sekiyama 120*1e9b65bbSMarkus Armbruster void error_setg_win32_internal(Error **errp, 121*1e9b65bbSMarkus Armbruster const char *src, int line, const char *func, 122*1e9b65bbSMarkus Armbruster int win32_err, const char *fmt, ...) 12320840d4cSTomoki Sekiyama { 12420840d4cSTomoki Sekiyama va_list ap; 12555237508SMarkus Armbruster char *msg1, *msg2; 12620840d4cSTomoki Sekiyama 12720840d4cSTomoki Sekiyama if (errp == NULL) { 12820840d4cSTomoki Sekiyama return; 12920840d4cSTomoki Sekiyama } 13020840d4cSTomoki Sekiyama 13120840d4cSTomoki Sekiyama va_start(ap, fmt); 132*1e9b65bbSMarkus Armbruster error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap); 13355237508SMarkus Armbruster va_end(ap); 13455237508SMarkus Armbruster 13520840d4cSTomoki Sekiyama if (win32_err != 0) { 13655237508SMarkus Armbruster msg1 = (*errp)->msg; 13755237508SMarkus Armbruster msg2 = g_win32_error_message(win32_err); 13855237508SMarkus Armbruster (*errp)->msg = g_strdup_printf("%s: %s (error: %x)", msg1, msg2, 13920840d4cSTomoki Sekiyama (unsigned)win32_err); 14020840d4cSTomoki Sekiyama g_free(msg2); 14120840d4cSTomoki Sekiyama g_free(msg1); 14220840d4cSTomoki Sekiyama } 14320840d4cSTomoki Sekiyama } 14420840d4cSTomoki Sekiyama 14520840d4cSTomoki Sekiyama #endif 14620840d4cSTomoki Sekiyama 147baacf047SPaolo Bonzini Error *error_copy(const Error *err) 148baacf047SPaolo Bonzini { 149baacf047SPaolo Bonzini Error *err_new; 150baacf047SPaolo Bonzini 151baacf047SPaolo Bonzini err_new = g_malloc0(sizeof(*err)); 152baacf047SPaolo Bonzini err_new->msg = g_strdup(err->msg); 153baacf047SPaolo Bonzini err_new->err_class = err->err_class; 154baacf047SPaolo Bonzini 155baacf047SPaolo Bonzini return err_new; 156baacf047SPaolo Bonzini } 157baacf047SPaolo Bonzini 158baacf047SPaolo Bonzini ErrorClass error_get_class(const Error *err) 159baacf047SPaolo Bonzini { 160baacf047SPaolo Bonzini return err->err_class; 161baacf047SPaolo Bonzini } 162baacf047SPaolo Bonzini 163baacf047SPaolo Bonzini const char *error_get_pretty(Error *err) 164baacf047SPaolo Bonzini { 165baacf047SPaolo Bonzini return err->msg; 166baacf047SPaolo Bonzini } 167baacf047SPaolo Bonzini 1682ee2f1e4SMarkus Armbruster void error_report_err(Error *err) 1692ee2f1e4SMarkus Armbruster { 1702ee2f1e4SMarkus Armbruster error_report("%s", error_get_pretty(err)); 1712ee2f1e4SMarkus Armbruster error_free(err); 1722ee2f1e4SMarkus Armbruster } 1732ee2f1e4SMarkus Armbruster 174baacf047SPaolo Bonzini void error_free(Error *err) 175baacf047SPaolo Bonzini { 176baacf047SPaolo Bonzini if (err) { 177baacf047SPaolo Bonzini g_free(err->msg); 178baacf047SPaolo Bonzini g_free(err); 179baacf047SPaolo Bonzini } 180baacf047SPaolo Bonzini } 181baacf047SPaolo Bonzini 18264dfefedSMarkus Armbruster void error_propagate(Error **dst_errp, Error *local_err) 183baacf047SPaolo Bonzini { 18464dfefedSMarkus Armbruster if (local_err && dst_errp == &error_abort) { 185*1e9b65bbSMarkus Armbruster error_do_abort(local_err); 18664dfefedSMarkus Armbruster } else if (dst_errp && !*dst_errp) { 18764dfefedSMarkus Armbruster *dst_errp = local_err; 188baacf047SPaolo Bonzini } else if (local_err) { 189baacf047SPaolo Bonzini error_free(local_err); 190baacf047SPaolo Bonzini } 191baacf047SPaolo Bonzini } 192