qemu/util/error.c
<<
>>
Prefs
   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 "qemu/error-report.h"
  16
  17struct Error
  18{
  19    char *msg;
  20    ErrorClass err_class;
  21};
  22
  23Error *error_abort;
  24
  25void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
  26{
  27    Error *err;
  28    va_list ap;
  29    int saved_errno = errno;
  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    if (errp == &error_abort) {
  44        error_report("%s", error_get_pretty(err));
  45        abort();
  46    }
  47
  48    *errp = err;
  49
  50    errno = saved_errno;
  51}
  52
  53void error_set_errno(Error **errp, int os_errno, ErrorClass err_class,
  54                     const char *fmt, ...)
  55{
  56    Error *err;
  57    char *msg1;
  58    va_list ap;
  59    int saved_errno = errno;
  60
  61    if (errp == NULL) {
  62        return;
  63    }
  64    assert(*errp == NULL);
  65
  66    err = g_malloc0(sizeof(*err));
  67
  68    va_start(ap, fmt);
  69    msg1 = g_strdup_vprintf(fmt, ap);
  70    if (os_errno != 0) {
  71        err->msg = g_strdup_printf("%s: %s", msg1, strerror(os_errno));
  72        g_free(msg1);
  73    } else {
  74        err->msg = msg1;
  75    }
  76    va_end(ap);
  77    err->err_class = err_class;
  78
  79    if (errp == &error_abort) {
  80        error_report("%s", error_get_pretty(err));
  81        abort();
  82    }
  83
  84    *errp = err;
  85
  86    errno = saved_errno;
  87}
  88
  89void error_setg_file_open(Error **errp, int os_errno, const char *filename)
  90{
  91    error_setg_errno(errp, os_errno, "Could not open '%s'", filename);
  92}
  93
  94#ifdef _WIN32
  95
  96void error_set_win32(Error **errp, int win32_err, ErrorClass err_class,
  97                     const char *fmt, ...)
  98{
  99    Error *err;
 100    char *msg1;
 101    va_list ap;
 102
 103    if (errp == NULL) {
 104        return;
 105    }
 106    assert(*errp == NULL);
 107
 108    err = g_malloc0(sizeof(*err));
 109
 110    va_start(ap, fmt);
 111    msg1 = g_strdup_vprintf(fmt, ap);
 112    if (win32_err != 0) {
 113        char *msg2 = g_win32_error_message(win32_err);
 114        err->msg = g_strdup_printf("%s: %s (error: %x)", msg1, msg2,
 115                                   (unsigned)win32_err);
 116        g_free(msg2);
 117        g_free(msg1);
 118    } else {
 119        err->msg = msg1;
 120    }
 121    va_end(ap);
 122    err->err_class = err_class;
 123
 124    if (errp == &error_abort) {
 125        error_report("%s", error_get_pretty(err));
 126        abort();
 127    }
 128
 129    *errp = err;
 130}
 131
 132#endif
 133
 134Error *error_copy(const Error *err)
 135{
 136    Error *err_new;
 137
 138    err_new = g_malloc0(sizeof(*err));
 139    err_new->msg = g_strdup(err->msg);
 140    err_new->err_class = err->err_class;
 141
 142    return err_new;
 143}
 144
 145ErrorClass error_get_class(const Error *err)
 146{
 147    return err->err_class;
 148}
 149
 150const char *error_get_pretty(Error *err)
 151{
 152    return err->msg;
 153}
 154
 155void error_free(Error *err)
 156{
 157    if (err) {
 158        g_free(err->msg);
 159        g_free(err);
 160    }
 161}
 162
 163void error_propagate(Error **dst_errp, Error *local_err)
 164{
 165    if (local_err && dst_errp == &error_abort) {
 166        error_report("%s", error_get_pretty(local_err));
 167        abort();
 168    } else if (dst_errp && !*dst_errp) {
 169        *dst_errp = local_err;
 170    } else if (local_err) {
 171        error_free(local_err);
 172    }
 173}
 174