Merge tag 'pull-sp-20240412' of https://gitlab.com/rth7680/qemu into staging
[qemu/armbru.git] / chardev / char-hmp-cmds.c
blob287c2b1bcd856f7e6a0fbbae85ded4d157dff609
1 /*
2 * HMP commands related to character devices
4 * Copyright IBM, Corp. 2011
6 * Authors:
7 * Anthony Liguori <aliguori@us.ibm.com>
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
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.
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"
26 void hmp_info_chardev(Monitor *mon, const QDict *qdict)
28 ChardevInfoList *char_info, *info;
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);
36 qapi_free_ChardevInfoList(char_info);
39 void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
41 const char *chardev = qdict_get_str(qdict, "device");
42 const char *data = qdict_get_str(qdict, "data");
43 Error *err = NULL;
45 qmp_ringbuf_write(chardev, data, false, 0, &err);
47 hmp_handle_error(mon, err);
50 void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
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;
58 data = qmp_ringbuf_read(chardev, size, false, 0, &err);
59 if (hmp_handle_error(mon, err)) {
60 return;
63 for (i = 0; data[i]; i++) {
64 unsigned char ch = data[i];
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);
75 monitor_printf(mon, "\n");
76 g_free(data);
79 void hmp_chardev_add(Monitor *mon, const QDict *qdict)
81 const char *args = qdict_get_str(qdict, "args");
82 Error *err = NULL;
83 QemuOpts *opts;
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);
92 hmp_handle_error(mon, err);
95 void hmp_chardev_change(Monitor *mon, const QDict *qdict)
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;
109 id = qdict_get_str(qdict, "id");
110 if (qemu_opts_id(opts)) {
111 error_setg(&err, "Unexpected 'id' parameter");
112 goto end;
115 backend = qemu_chr_parse_opts(opts, &err);
116 if (!backend) {
117 goto end;
120 ret = qmp_chardev_change(id, backend, &err);
122 end:
123 qapi_free_ChardevReturn(ret);
124 qapi_free_ChardevBackend(backend);
125 qemu_opts_del(opts);
126 hmp_handle_error(mon, err);
129 void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
131 Error *local_err = NULL;
133 qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
134 hmp_handle_error(mon, local_err);
137 void hmp_chardev_send_break(Monitor *mon, const QDict *qdict)
139 Error *local_err = NULL;
141 qmp_chardev_send_break(qdict_get_str(qdict, "id"), &local_err);
142 hmp_handle_error(mon, local_err);
145 void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str)
147 size_t len;
148 ChardevBackendInfoList *list, *start;
150 if (nb_args != 2) {
151 return;
153 len = strlen(str);
154 readline_set_completion_index(rs, len);
156 start = list = qmp_query_chardev_backends(NULL);
157 while (list) {
158 const char *chr_name = list->value->name;
160 if (!strncmp(chr_name, str, len)) {
161 readline_add_completion(rs, chr_name);
163 list = list->next;
165 qapi_free_ChardevBackendInfoList(start);
168 void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str)
170 size_t len;
171 ChardevInfoList *list, *start;
173 if (nb_args != 2) {
174 return;
176 len = strlen(str);
177 readline_set_completion_index(rs, len);
179 start = list = qmp_query_chardev(NULL);
180 while (list) {
181 ChardevInfo *chr = list->value;
183 if (!strncmp(chr->label, str, len)) {
184 readline_add_completion(rs, chr->label);
186 list = list->next;
188 qapi_free_ChardevInfoList(start);
191 static void ringbuf_completion(ReadLineState *rs, const char *str)
193 size_t len;
194 ChardevInfoList *list, *start;
196 len = strlen(str);
197 readline_set_completion_index(rs, len);
199 start = list = qmp_query_chardev(NULL);
200 while (list) {
201 ChardevInfo *chr_info = list->value;
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);
209 list = list->next;
211 qapi_free_ChardevInfoList(start);
214 void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str)
216 if (nb_args != 2) {
217 return;
219 ringbuf_completion(rs, str);