Revision 6e4f984c

b/monitor.c
3971 3971
    if (!cmd)
3972 3972
        goto out;
3973 3973

  
3974
    qemu_errors_to_mon(mon);
3975

  
3976 3974
    if (monitor_handler_is_async(cmd)) {
3977 3975
        user_async_cmd_handler(mon, cmd, qdict);
3978 3976
    } else if (monitor_handler_ported(cmd)) {
......
3984 3982
    if (monitor_has_error(mon))
3985 3983
        monitor_print_error(mon);
3986 3984

  
3987
    qemu_errors_to_previous();
3988

  
3989 3985
out:
3990 3986
    QDECREF(qdict);
3991 3987
}
......
4387 4383
    const char *cmd_name, *info_item;
4388 4384

  
4389 4385
    args = NULL;
4390
    qemu_errors_to_mon(mon);
4391 4386

  
4392 4387
    obj = json_parser_parse(tokens, NULL);
4393 4388
    if (!obj) {
......
4468 4463
    monitor_protocol_emitter(mon, NULL);
4469 4464
out:
4470 4465
    QDECREF(args);
4471
    qemu_errors_to_previous();
4472 4466
}
4473 4467

  
4474 4468
/**
b/qemu-error.c
2 2
#include "monitor.h"
3 3
#include "sysemu.h"
4 4

  
5
typedef struct QemuErrorSink QemuErrorSink;
6
struct QemuErrorSink {
7
    enum {
8
        ERR_SINK_FILE,
9
        ERR_SINK_MONITOR,
10
    } dest;
11
    union {
12
        FILE    *fp;
13
        Monitor *mon;
14
    };
15
    QemuErrorSink *previous;
16
};
17

  
18
static QemuErrorSink *qemu_error_sink;
19

  
20
void qemu_errors_to_file(FILE *fp)
21
{
22
    QemuErrorSink *sink;
23

  
24
    sink = qemu_mallocz(sizeof(*sink));
25
    sink->dest = ERR_SINK_FILE;
26
    sink->fp = fp;
27
    sink->previous = qemu_error_sink;
28
    qemu_error_sink = sink;
29
}
30

  
31
void qemu_errors_to_mon(Monitor *mon)
32
{
33
    QemuErrorSink *sink;
34

  
35
    sink = qemu_mallocz(sizeof(*sink));
36
    sink->dest = ERR_SINK_MONITOR;
37
    sink->mon = mon;
38
    sink->previous = qemu_error_sink;
39
    qemu_error_sink = sink;
40
}
41

  
42
void qemu_errors_to_previous(void)
43
{
44
    QemuErrorSink *sink;
45

  
46
    assert(qemu_error_sink != NULL);
47
    sink = qemu_error_sink;
48
    qemu_error_sink = sink->previous;
49
    qemu_free(sink);
50
}
51

  
52 5
void qemu_error(const char *fmt, ...)
53 6
{
54 7
    va_list args;
55 8

  
56
    assert(qemu_error_sink != NULL);
57
    switch (qemu_error_sink->dest) {
58
    case ERR_SINK_FILE:
59
        va_start(args, fmt);
60
        vfprintf(qemu_error_sink->fp, fmt, args);
61
        va_end(args);
62
        break;
63
    case ERR_SINK_MONITOR:
64
        va_start(args, fmt);
65
        monitor_vprintf(qemu_error_sink->mon, fmt, args);
66
        va_end(args);
67
        break;
9
    va_start(args, fmt);
10
    if (cur_mon) {
11
        monitor_vprintf(cur_mon, fmt, args);
12
    } else {
13
        vfprintf(stderr, fmt, args);
68 14
    }
15
    va_end(args);
69 16
}
70 17

  
71 18
void qemu_error_internal(const char *file, int linenr, const char *func,
......
74 21
    va_list va;
75 22
    QError *qerror;
76 23

  
77
    assert(qemu_error_sink != NULL);
78

  
79 24
    va_start(va, fmt);
80 25
    qerror = qerror_from_info(file, linenr, func, fmt, &va);
81 26
    va_end(va);
82 27

  
83
    switch (qemu_error_sink->dest) {
84
    case ERR_SINK_FILE:
28
    if (cur_mon) {
29
        monitor_set_error(cur_mon, qerror);
30
    } else {
85 31
        qerror_print(qerror);
86 32
        QDECREF(qerror);
87
        break;
88
    case ERR_SINK_MONITOR:
89
        monitor_set_error(qemu_error_sink->mon, qerror);
90
        break;
91 33
    }
92 34
}
b/sysemu.h
73 73
void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f);
74 74
int qemu_loadvm_state(QEMUFile *f);
75 75

  
76
void qemu_errors_to_file(FILE *fp);
77
void qemu_errors_to_mon(Monitor *mon);
78
void qemu_errors_to_previous(void);
79 76
void qemu_error(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
80 77
void qemu_error_internal(const char *file, int linenr, const char *func,
81 78
                         const char *fmt, ...)
b/vl.c
4864 4864

  
4865 4865
    init_clocks();
4866 4866

  
4867
    qemu_errors_to_file(stderr);
4868 4867
    qemu_cache_utils_init(envp);
4869 4868

  
4870 4869
    QLIST_INIT (&vm_change_state_head);

Also available in: Unified diff