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 Error *error_copy(const Error *err) 75 { 76 Error *err_new; 77 78 err_new = g_malloc0(sizeof(*err)); 79 err_new->msg = g_strdup(err->msg); 80 err_new->err_class = err->err_class; 81 82 return err_new; 83 } 84 85 bool error_is_set(Error **errp) 86 { 87 return (errp && *errp); 88 } 89 90 ErrorClass error_get_class(const Error *err) 91 { 92 return err->err_class; 93 } 94 95 const char *error_get_pretty(Error *err) 96 { 97 return err->msg; 98 } 99 100 void error_free(Error *err) 101 { 102 if (err) { 103 g_free(err->msg); 104 g_free(err); 105 } 106 } 107 108 void error_propagate(Error **dst_err, Error *local_err) 109 { 110 if (dst_err && !*dst_err) { 111 *dst_err = local_err; 112 } else if (local_err) { 113 error_free(local_err); 114 } 115 } 116