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 13 #include "qemu-common.h" 14 #include "qapi/error.h" 15 #include "qapi/qmp/qjson.h" 16 #include "qapi/qmp/qdict.h" 17 #include "qapi-types.h" 18 #include "qapi/qmp/qerror.h" 19 20 struct Error 21 { 22 char *msg; 23 ErrorClass err_class; 24 }; 25 26 void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...) 27 { 28 Error *err; 29 va_list ap; 30 31 if (errp == NULL) { 32 return; 33 } 34 assert(*errp == NULL); 35 36 err = g_malloc0(sizeof(*err)); 37 38 va_start(ap, fmt); 39 err->msg = g_strdup_vprintf(fmt, ap); 40 va_end(ap); 41 err->err_class = err_class; 42 43 *errp = err; 44 } 45 46 void error_set_errno(Error **errp, int os_errno, ErrorClass err_class, 47 const char *fmt, ...) 48 { 49 Error *err; 50 char *msg1; 51 va_list ap; 52 53 if (errp == NULL) { 54 return; 55 } 56 assert(*errp == NULL); 57 58 err = g_malloc0(sizeof(*err)); 59 60 va_start(ap, fmt); 61 msg1 = g_strdup_vprintf(fmt, ap); 62 if (os_errno != 0) { 63 err->msg = g_strdup_printf("%s: %s", msg1, strerror(os_errno)); 64 g_free(msg1); 65 } else { 66 err->msg = msg1; 67 } 68 va_end(ap); 69 err->err_class = err_class; 70 71 *errp = err; 72 } 73 74 void error_setg_file_open(Error **errp, int os_errno, const char *filename) 75 { 76 error_setg_errno(errp, os_errno, "Could not open '%s'", filename); 77 } 78 79 Error *error_copy(const Error *err) 80 { 81 Error *err_new; 82 83 err_new = g_malloc0(sizeof(*err)); 84 err_new->msg = g_strdup(err->msg); 85 err_new->err_class = err->err_class; 86 87 return err_new; 88 } 89 90 bool error_is_set(Error **errp) 91 { 92 return (errp && *errp); 93 } 94 95 ErrorClass error_get_class(const Error *err) 96 { 97 return err->err_class; 98 } 99 100 const char *error_get_pretty(Error *err) 101 { 102 return err->msg; 103 } 104 105 void error_free(Error *err) 106 { 107 if (err) { 108 g_free(err->msg); 109 g_free(err); 110 } 111 } 112 113 void error_propagate(Error **dst_err, Error *local_err) 114 { 115 if (dst_err && !*dst_err) { 116 *dst_err = local_err; 117 } else if (local_err) { 118 error_free(local_err); 119 } 120 } 121