]> git.proxmox.com Git - mirror_qemu.git/blame - chardev/char-hmp-cmds.c
block: Mark bdrv_probe_blocksizes() and callers GRAPH_RDLOCK
[mirror_qemu.git] / chardev / char-hmp-cmds.c
CommitLineData
b7d75c0b
MA
1/*
2 * HMP commands related to character devices
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 GPL, version 2. See
10 * the COPYING file in the top-level directory.
11 *
12 * Contributions after 2012-01-13 are licensed under the terms of the
13 * GNU GPL, version 2 or (at your option) any later version.
14 */
15
16#include "qemu/osdep.h"
17#include "chardev/char.h"
18#include "monitor/hmp.h"
19#include "monitor/monitor.h"
20#include "qapi/error.h"
21#include "qapi/qapi-commands-char.h"
22#include "qapi/qmp/qdict.h"
23#include "qemu/config-file.h"
24#include "qemu/option.h"
25
26void hmp_info_chardev(Monitor *mon, const QDict *qdict)
27{
28 ChardevInfoList *char_info, *info;
29
30 char_info = qmp_query_chardev(NULL);
31 for (info = char_info; info; info = info->next) {
32 monitor_printf(mon, "%s: filename=%s\n", info->value->label,
33 info->value->filename);
34 }
35
36 qapi_free_ChardevInfoList(char_info);
37}
38
39void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
40{
41 const char *chardev = qdict_get_str(qdict, "device");
42 const char *data = qdict_get_str(qdict, "data");
43 Error *err = NULL;
44
45 qmp_ringbuf_write(chardev, data, false, 0, &err);
46
47 hmp_handle_error(mon, err);
48}
49
50void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
51{
52 uint32_t size = qdict_get_int(qdict, "size");
53 const char *chardev = qdict_get_str(qdict, "device");
54 char *data;
55 Error *err = NULL;
56 int i;
57
58 data = qmp_ringbuf_read(chardev, size, false, 0, &err);
59 if (hmp_handle_error(mon, err)) {
60 return;
61 }
62
63 for (i = 0; data[i]; i++) {
64 unsigned char ch = data[i];
65
66 if (ch == '\\') {
67 monitor_printf(mon, "\\\\");
68 } else if ((ch < 0x20 && ch != '\n' && ch != '\t') || ch == 0x7F) {
69 monitor_printf(mon, "\\u%04X", ch);
70 } else {
71 monitor_printf(mon, "%c", ch);
72 }
73
74 }
75 monitor_printf(mon, "\n");
76 g_free(data);
77}
78
79void hmp_chardev_add(Monitor *mon, const QDict *qdict)
80{
81 const char *args = qdict_get_str(qdict, "args");
82 Error *err = NULL;
83 QemuOpts *opts;
84
85 opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args, true);
86 if (opts == NULL) {
87 error_setg(&err, "Parsing chardev args failed");
88 } else {
89 qemu_chr_new_from_opts(opts, NULL, &err);
90 qemu_opts_del(opts);
91 }
92 hmp_handle_error(mon, err);
93}
94
95void hmp_chardev_change(Monitor *mon, const QDict *qdict)
96{
97 const char *args = qdict_get_str(qdict, "args");
98 const char *id;
99 Error *err = NULL;
100 ChardevBackend *backend = NULL;
101 ChardevReturn *ret = NULL;
102 QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args,
103 true);
104 if (!opts) {
105 error_setg(&err, "Parsing chardev args failed");
106 goto end;
107 }
108
109 id = qdict_get_str(qdict, "id");
110 if (qemu_opts_id(opts)) {
111 error_setg(&err, "Unexpected 'id' parameter");
112 goto end;
113 }
114
115 backend = qemu_chr_parse_opts(opts, &err);
116 if (!backend) {
117 goto end;
118 }
119
120 ret = qmp_chardev_change(id, backend, &err);
121
122end:
123 qapi_free_ChardevReturn(ret);
124 qapi_free_ChardevBackend(backend);
125 qemu_opts_del(opts);
126 hmp_handle_error(mon, err);
127}
128
129void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
130{
131 Error *local_err = NULL;
132
133 qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
134 hmp_handle_error(mon, local_err);
135}
136
137void hmp_chardev_send_break(Monitor *mon, const QDict *qdict)
138{
139 Error *local_err = NULL;
140
141 qmp_chardev_send_break(qdict_get_str(qdict, "id"), &local_err);
142 hmp_handle_error(mon, local_err);
143}
144
145void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str)
146{
147 size_t len;
148 ChardevBackendInfoList *list, *start;
149
150 if (nb_args != 2) {
151 return;
152 }
153 len = strlen(str);
154 readline_set_completion_index(rs, len);
155
156 start = list = qmp_query_chardev_backends(NULL);
157 while (list) {
158 const char *chr_name = list->value->name;
159
160 if (!strncmp(chr_name, str, len)) {
161 readline_add_completion(rs, chr_name);
162 }
163 list = list->next;
164 }
165 qapi_free_ChardevBackendInfoList(start);
166}
167
168void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str)
169{
170 size_t len;
171 ChardevInfoList *list, *start;
172
173 if (nb_args != 2) {
174 return;
175 }
176 len = strlen(str);
177 readline_set_completion_index(rs, len);
178
179 start = list = qmp_query_chardev(NULL);
180 while (list) {
181 ChardevInfo *chr = list->value;
182
183 if (!strncmp(chr->label, str, len)) {
184 readline_add_completion(rs, chr->label);
185 }
186 list = list->next;
187 }
188 qapi_free_ChardevInfoList(start);
189}
190
191static void ringbuf_completion(ReadLineState *rs, const char *str)
192{
193 size_t len;
194 ChardevInfoList *list, *start;
195
196 len = strlen(str);
197 readline_set_completion_index(rs, len);
198
199 start = list = qmp_query_chardev(NULL);
200 while (list) {
201 ChardevInfo *chr_info = list->value;
202
203 if (!strncmp(chr_info->label, str, len)) {
204 Chardev *chr = qemu_chr_find(chr_info->label);
205 if (chr && CHARDEV_IS_RINGBUF(chr)) {
206 readline_add_completion(rs, chr_info->label);
207 }
208 }
209 list = list->next;
210 }
211 qapi_free_ChardevInfoList(start);
212}
213
214void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str)
215{
216 if (nb_args != 2) {
217 return;
218 }
219 ringbuf_completion(rs, str);
220}