char-hmp-cmds.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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. #include "qemu/osdep.h"
  16. #include "chardev/char.h"
  17. #include "monitor/hmp.h"
  18. #include "monitor/monitor.h"
  19. #include "qapi/error.h"
  20. #include "qapi/qapi-commands-char.h"
  21. #include "qapi/qmp/qdict.h"
  22. #include "qemu/config-file.h"
  23. #include "qemu/option.h"
  24. void hmp_info_chardev(Monitor *mon, const QDict *qdict)
  25. {
  26. ChardevInfoList *char_info, *info;
  27. char_info = qmp_query_chardev(NULL);
  28. for (info = char_info; info; info = info->next) {
  29. monitor_printf(mon, "%s: filename=%s\n", info->value->label,
  30. info->value->filename);
  31. }
  32. qapi_free_ChardevInfoList(char_info);
  33. }
  34. void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
  35. {
  36. const char *chardev = qdict_get_str(qdict, "device");
  37. const char *data = qdict_get_str(qdict, "data");
  38. Error *err = NULL;
  39. qmp_ringbuf_write(chardev, data, false, 0, &err);
  40. hmp_handle_error(mon, err);
  41. }
  42. void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
  43. {
  44. uint32_t size = qdict_get_int(qdict, "size");
  45. const char *chardev = qdict_get_str(qdict, "device");
  46. char *data;
  47. Error *err = NULL;
  48. int i;
  49. data = qmp_ringbuf_read(chardev, size, false, 0, &err);
  50. if (hmp_handle_error(mon, err)) {
  51. return;
  52. }
  53. for (i = 0; data[i]; i++) {
  54. unsigned char ch = data[i];
  55. if (ch == '\\') {
  56. monitor_printf(mon, "\\\\");
  57. } else if ((ch < 0x20 && ch != '\n' && ch != '\t') || ch == 0x7F) {
  58. monitor_printf(mon, "\\u%04X", ch);
  59. } else {
  60. monitor_printf(mon, "%c", ch);
  61. }
  62. }
  63. monitor_printf(mon, "\n");
  64. g_free(data);
  65. }
  66. void hmp_chardev_add(Monitor *mon, const QDict *qdict)
  67. {
  68. const char *args = qdict_get_str(qdict, "args");
  69. Error *err = NULL;
  70. QemuOpts *opts;
  71. opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args, true);
  72. if (opts == NULL) {
  73. error_setg(&err, "Parsing chardev args failed");
  74. } else {
  75. qemu_chr_new_from_opts(opts, NULL, &err);
  76. qemu_opts_del(opts);
  77. }
  78. hmp_handle_error(mon, err);
  79. }
  80. void hmp_chardev_change(Monitor *mon, const QDict *qdict)
  81. {
  82. const char *args = qdict_get_str(qdict, "args");
  83. const char *id;
  84. Error *err = NULL;
  85. ChardevBackend *backend = NULL;
  86. ChardevReturn *ret = NULL;
  87. QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), args,
  88. true);
  89. if (!opts) {
  90. error_setg(&err, "Parsing chardev args failed");
  91. goto end;
  92. }
  93. id = qdict_get_str(qdict, "id");
  94. if (qemu_opts_id(opts)) {
  95. error_setg(&err, "Unexpected 'id' parameter");
  96. goto end;
  97. }
  98. backend = qemu_chr_parse_opts(opts, &err);
  99. if (!backend) {
  100. goto end;
  101. }
  102. ret = qmp_chardev_change(id, backend, &err);
  103. end:
  104. qapi_free_ChardevReturn(ret);
  105. qapi_free_ChardevBackend(backend);
  106. qemu_opts_del(opts);
  107. hmp_handle_error(mon, err);
  108. }
  109. void hmp_chardev_remove(Monitor *mon, const QDict *qdict)
  110. {
  111. Error *local_err = NULL;
  112. qmp_chardev_remove(qdict_get_str(qdict, "id"), &local_err);
  113. hmp_handle_error(mon, local_err);
  114. }
  115. void hmp_chardev_send_break(Monitor *mon, const QDict *qdict)
  116. {
  117. Error *local_err = NULL;
  118. qmp_chardev_send_break(qdict_get_str(qdict, "id"), &local_err);
  119. hmp_handle_error(mon, local_err);
  120. }
  121. void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str)
  122. {
  123. size_t len;
  124. ChardevBackendInfoList *list, *start;
  125. if (nb_args != 2) {
  126. return;
  127. }
  128. len = strlen(str);
  129. readline_set_completion_index(rs, len);
  130. start = list = qmp_query_chardev_backends(NULL);
  131. while (list) {
  132. const char *chr_name = list->value->name;
  133. if (!strncmp(chr_name, str, len)) {
  134. readline_add_completion(rs, chr_name);
  135. }
  136. list = list->next;
  137. }
  138. qapi_free_ChardevBackendInfoList(start);
  139. }
  140. void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str)
  141. {
  142. size_t len;
  143. ChardevInfoList *list, *start;
  144. if (nb_args != 2) {
  145. return;
  146. }
  147. len = strlen(str);
  148. readline_set_completion_index(rs, len);
  149. start = list = qmp_query_chardev(NULL);
  150. while (list) {
  151. ChardevInfo *chr = list->value;
  152. if (!strncmp(chr->label, str, len)) {
  153. readline_add_completion(rs, chr->label);
  154. }
  155. list = list->next;
  156. }
  157. qapi_free_ChardevInfoList(start);
  158. }
  159. static void ringbuf_completion(ReadLineState *rs, const char *str)
  160. {
  161. size_t len;
  162. ChardevInfoList *list, *start;
  163. len = strlen(str);
  164. readline_set_completion_index(rs, len);
  165. start = list = qmp_query_chardev(NULL);
  166. while (list) {
  167. ChardevInfo *chr_info = list->value;
  168. if (!strncmp(chr_info->label, str, len)) {
  169. Chardev *chr = qemu_chr_find(chr_info->label);
  170. if (chr && CHARDEV_IS_RINGBUF(chr)) {
  171. readline_add_completion(rs, chr_info->label);
  172. }
  173. }
  174. list = list->next;
  175. }
  176. qapi_free_ChardevInfoList(start);
  177. }
  178. void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str)
  179. {
  180. if (nb_args != 2) {
  181. return;
  182. }
  183. ringbuf_completion(rs, str);
  184. }