]>
Commit | Line | Data |
---|---|---|
b4a51f7f MA |
1 | #include <stdio.h> |
2 | #include "monitor.h" | |
3 | #include "sysemu.h" | |
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 | void qemu_error(const char *fmt, ...) | |
53 | { | |
54 | va_list args; | |
55 | ||
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; | |
68 | } | |
69 | } | |
70 | ||
71 | void qemu_error_internal(const char *file, int linenr, const char *func, | |
72 | const char *fmt, ...) | |
73 | { | |
74 | va_list va; | |
75 | QError *qerror; | |
76 | ||
77 | assert(qemu_error_sink != NULL); | |
78 | ||
79 | va_start(va, fmt); | |
80 | qerror = qerror_from_info(file, linenr, func, fmt, &va); | |
81 | va_end(va); | |
82 | ||
83 | switch (qemu_error_sink->dest) { | |
84 | case ERR_SINK_FILE: | |
85 | qerror_print(qerror); | |
86 | QDECREF(qerror); | |
87 | break; | |
88 | case ERR_SINK_MONITOR: | |
89 | monitor_set_error(qemu_error_sink->mon, qerror); | |
90 | break; | |
91 | } | |
92 | } |