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" 15baacf047SPaolo Bonzini #include "qapi/qmp/qjson.h" 16baacf047SPaolo Bonzini #include "qapi/qmp/qdict.h" 17baacf047SPaolo Bonzini #include "qapi-types.h" 18baacf047SPaolo Bonzini #include "qapi/qmp/qerror.h" 19baacf047SPaolo Bonzini 20baacf047SPaolo Bonzini struct Error 21baacf047SPaolo Bonzini { 22baacf047SPaolo Bonzini char *msg; 23baacf047SPaolo Bonzini ErrorClass err_class; 24baacf047SPaolo Bonzini }; 25baacf047SPaolo Bonzini 26baacf047SPaolo Bonzini void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...) 27baacf047SPaolo Bonzini { 28baacf047SPaolo Bonzini Error *err; 29baacf047SPaolo Bonzini va_list ap; 30baacf047SPaolo Bonzini 31baacf047SPaolo Bonzini if (errp == NULL) { 32baacf047SPaolo Bonzini return; 33baacf047SPaolo Bonzini } 34baacf047SPaolo Bonzini assert(*errp == NULL); 35baacf047SPaolo Bonzini 36baacf047SPaolo Bonzini err = g_malloc0(sizeof(*err)); 37baacf047SPaolo Bonzini 38baacf047SPaolo Bonzini va_start(ap, fmt); 39baacf047SPaolo Bonzini err->msg = g_strdup_vprintf(fmt, ap); 40baacf047SPaolo Bonzini va_end(ap); 41baacf047SPaolo Bonzini err->err_class = err_class; 42baacf047SPaolo Bonzini 43baacf047SPaolo Bonzini *errp = err; 44baacf047SPaolo Bonzini } 45baacf047SPaolo Bonzini 46baacf047SPaolo Bonzini void error_set_errno(Error **errp, int os_errno, ErrorClass err_class, 47baacf047SPaolo Bonzini const char *fmt, ...) 48baacf047SPaolo Bonzini { 49baacf047SPaolo Bonzini Error *err; 50baacf047SPaolo Bonzini char *msg1; 51baacf047SPaolo Bonzini va_list ap; 52baacf047SPaolo Bonzini 53baacf047SPaolo Bonzini if (errp == NULL) { 54baacf047SPaolo Bonzini return; 55baacf047SPaolo Bonzini } 56baacf047SPaolo Bonzini assert(*errp == NULL); 57baacf047SPaolo Bonzini 58baacf047SPaolo Bonzini err = g_malloc0(sizeof(*err)); 59baacf047SPaolo Bonzini 60baacf047SPaolo Bonzini va_start(ap, fmt); 61baacf047SPaolo Bonzini msg1 = g_strdup_vprintf(fmt, ap); 62baacf047SPaolo Bonzini if (os_errno != 0) { 63baacf047SPaolo Bonzini err->msg = g_strdup_printf("%s: %s", msg1, strerror(os_errno)); 64baacf047SPaolo Bonzini g_free(msg1); 65baacf047SPaolo Bonzini } else { 66baacf047SPaolo Bonzini err->msg = msg1; 67baacf047SPaolo Bonzini } 68baacf047SPaolo Bonzini va_end(ap); 69baacf047SPaolo Bonzini err->err_class = err_class; 70baacf047SPaolo Bonzini 71baacf047SPaolo Bonzini *errp = err; 72baacf047SPaolo Bonzini } 73baacf047SPaolo Bonzini 7454028d75SLuiz Capitulino void error_setg_file_open(Error **errp, int os_errno, const char *filename) 7554028d75SLuiz Capitulino { 7654028d75SLuiz Capitulino error_setg_errno(errp, os_errno, "Could not open '%s'", filename); 7754028d75SLuiz Capitulino } 7854028d75SLuiz Capitulino 79*20840d4cSTomoki Sekiyama #ifdef _WIN32 80*20840d4cSTomoki Sekiyama 81*20840d4cSTomoki Sekiyama void error_set_win32(Error **errp, int win32_err, ErrorClass err_class, 82*20840d4cSTomoki Sekiyama const char *fmt, ...) 83*20840d4cSTomoki Sekiyama { 84*20840d4cSTomoki Sekiyama Error *err; 85*20840d4cSTomoki Sekiyama char *msg1; 86*20840d4cSTomoki Sekiyama va_list ap; 87*20840d4cSTomoki Sekiyama 88*20840d4cSTomoki Sekiyama if (errp == NULL) { 89*20840d4cSTomoki Sekiyama return; 90*20840d4cSTomoki Sekiyama } 91*20840d4cSTomoki Sekiyama assert(*errp == NULL); 92*20840d4cSTomoki Sekiyama 93*20840d4cSTomoki Sekiyama err = g_malloc0(sizeof(*err)); 94*20840d4cSTomoki Sekiyama 95*20840d4cSTomoki Sekiyama va_start(ap, fmt); 96*20840d4cSTomoki Sekiyama msg1 = g_strdup_vprintf(fmt, ap); 97*20840d4cSTomoki Sekiyama if (win32_err != 0) { 98*20840d4cSTomoki Sekiyama char *msg2 = g_win32_error_message(win32_err); 99*20840d4cSTomoki Sekiyama err->msg = g_strdup_printf("%s: %s (error: %x)", msg1, msg2, 100*20840d4cSTomoki Sekiyama (unsigned)win32_err); 101*20840d4cSTomoki Sekiyama g_free(msg2); 102*20840d4cSTomoki Sekiyama g_free(msg1); 103*20840d4cSTomoki Sekiyama } else { 104*20840d4cSTomoki Sekiyama err->msg = msg1; 105*20840d4cSTomoki Sekiyama } 106*20840d4cSTomoki Sekiyama va_end(ap); 107*20840d4cSTomoki Sekiyama err->err_class = err_class; 108*20840d4cSTomoki Sekiyama 109*20840d4cSTomoki Sekiyama *errp = err; 110*20840d4cSTomoki Sekiyama } 111*20840d4cSTomoki Sekiyama 112*20840d4cSTomoki Sekiyama #endif 113*20840d4cSTomoki Sekiyama 114baacf047SPaolo Bonzini Error *error_copy(const Error *err) 115baacf047SPaolo Bonzini { 116baacf047SPaolo Bonzini Error *err_new; 117baacf047SPaolo Bonzini 118baacf047SPaolo Bonzini err_new = g_malloc0(sizeof(*err)); 119baacf047SPaolo Bonzini err_new->msg = g_strdup(err->msg); 120baacf047SPaolo Bonzini err_new->err_class = err->err_class; 121baacf047SPaolo Bonzini 122baacf047SPaolo Bonzini return err_new; 123baacf047SPaolo Bonzini } 124baacf047SPaolo Bonzini 125baacf047SPaolo Bonzini bool error_is_set(Error **errp) 126baacf047SPaolo Bonzini { 127baacf047SPaolo Bonzini return (errp && *errp); 128baacf047SPaolo Bonzini } 129baacf047SPaolo Bonzini 130baacf047SPaolo Bonzini ErrorClass error_get_class(const Error *err) 131baacf047SPaolo Bonzini { 132baacf047SPaolo Bonzini return err->err_class; 133baacf047SPaolo Bonzini } 134baacf047SPaolo Bonzini 135baacf047SPaolo Bonzini const char *error_get_pretty(Error *err) 136baacf047SPaolo Bonzini { 137baacf047SPaolo Bonzini return err->msg; 138baacf047SPaolo Bonzini } 139baacf047SPaolo Bonzini 140baacf047SPaolo Bonzini void error_free(Error *err) 141baacf047SPaolo Bonzini { 142baacf047SPaolo Bonzini if (err) { 143baacf047SPaolo Bonzini g_free(err->msg); 144baacf047SPaolo Bonzini g_free(err); 145baacf047SPaolo Bonzini } 146baacf047SPaolo Bonzini } 147baacf047SPaolo Bonzini 148baacf047SPaolo Bonzini void error_propagate(Error **dst_err, Error *local_err) 149baacf047SPaolo Bonzini { 150baacf047SPaolo Bonzini if (dst_err && !*dst_err) { 151baacf047SPaolo Bonzini *dst_err = local_err; 152baacf047SPaolo Bonzini } else if (local_err) { 153baacf047SPaolo Bonzini error_free(local_err); 154baacf047SPaolo Bonzini } 155baacf047SPaolo Bonzini } 156