2
0

char-io.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * QEMU System Emulator
  3. *
  4. * Copyright (c) 2003-2008 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "qemu/osdep.h"
  25. #include "chardev/char-io.h"
  26. typedef struct IOWatchPoll {
  27. GSource parent;
  28. QIOChannel *ioc;
  29. GSource *src;
  30. IOCanReadHandler *fd_can_read;
  31. GSourceFunc fd_read;
  32. void *opaque;
  33. GMainContext *context;
  34. } IOWatchPoll;
  35. static IOWatchPoll *io_watch_poll_from_source(GSource *source)
  36. {
  37. return container_of(source, IOWatchPoll, parent);
  38. }
  39. static gboolean io_watch_poll_prepare(GSource *source,
  40. gint *timeout)
  41. {
  42. IOWatchPoll *iwp = io_watch_poll_from_source(source);
  43. bool now_active = iwp->fd_can_read(iwp->opaque) > 0;
  44. bool was_active = iwp->src != NULL;
  45. if (was_active == now_active) {
  46. return FALSE;
  47. }
  48. /*
  49. * We do not register the QIOChannel watch as a child GSource.
  50. * The 'prepare' function on the parent GSource will be
  51. * skipped if a child GSource's 'prepare' function indicates
  52. * readiness. We need this prepare function be guaranteed
  53. * to run on *every* iteration of the main loop, because
  54. * it is critical to ensure we remove the QIOChannel watch
  55. * if 'fd_can_read' indicates the frontend cannot receive
  56. * more data.
  57. */
  58. if (now_active) {
  59. iwp->src = qio_channel_create_watch(
  60. iwp->ioc, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL);
  61. g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
  62. g_source_attach(iwp->src, iwp->context);
  63. } else {
  64. g_source_destroy(iwp->src);
  65. g_source_unref(iwp->src);
  66. iwp->src = NULL;
  67. }
  68. return FALSE;
  69. }
  70. static gboolean io_watch_poll_check(GSource *source)
  71. {
  72. return FALSE;
  73. }
  74. static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
  75. gpointer user_data)
  76. {
  77. abort();
  78. }
  79. static void io_watch_poll_finalize(GSource *source)
  80. {
  81. IOWatchPoll *iwp = io_watch_poll_from_source(source);
  82. if (iwp->src) {
  83. g_source_destroy(iwp->src);
  84. g_source_unref(iwp->src);
  85. iwp->src = NULL;
  86. }
  87. }
  88. static GSourceFuncs io_watch_poll_funcs = {
  89. .prepare = io_watch_poll_prepare,
  90. .check = io_watch_poll_check,
  91. .dispatch = io_watch_poll_dispatch,
  92. .finalize = io_watch_poll_finalize,
  93. };
  94. GSource *io_add_watch_poll(Chardev *chr,
  95. QIOChannel *ioc,
  96. IOCanReadHandler *fd_can_read,
  97. QIOChannelFunc fd_read,
  98. gpointer user_data,
  99. GMainContext *context)
  100. {
  101. IOWatchPoll *iwp;
  102. char *name;
  103. iwp = (IOWatchPoll *) g_source_new(&io_watch_poll_funcs,
  104. sizeof(IOWatchPoll));
  105. iwp->fd_can_read = fd_can_read;
  106. iwp->opaque = user_data;
  107. iwp->ioc = ioc;
  108. iwp->fd_read = (GSourceFunc) fd_read;
  109. iwp->src = NULL;
  110. iwp->context = context;
  111. name = g_strdup_printf("chardev-iowatch-%s", chr->label);
  112. g_source_set_name((GSource *)iwp, name);
  113. g_free(name);
  114. g_source_attach(&iwp->parent, context);
  115. g_source_unref(&iwp->parent);
  116. return (GSource *)iwp;
  117. }
  118. static void io_remove_watch_poll(GSource *source)
  119. {
  120. IOWatchPoll *iwp;
  121. iwp = io_watch_poll_from_source(source);
  122. g_source_destroy(&iwp->parent);
  123. }
  124. void remove_fd_in_watch(Chardev *chr)
  125. {
  126. if (chr->gsource) {
  127. io_remove_watch_poll(chr->gsource);
  128. chr->gsource = NULL;
  129. }
  130. }
  131. int io_channel_send_full(QIOChannel *ioc,
  132. const void *buf, size_t len,
  133. int *fds, size_t nfds)
  134. {
  135. size_t offset = 0;
  136. while (offset < len) {
  137. ssize_t ret = 0;
  138. struct iovec iov = { .iov_base = (char *)buf + offset,
  139. .iov_len = len - offset };
  140. ret = qio_channel_writev_full(
  141. ioc, &iov, 1,
  142. fds, nfds, 0, NULL);
  143. if (ret == QIO_CHANNEL_ERR_BLOCK) {
  144. if (offset) {
  145. return offset;
  146. }
  147. errno = EAGAIN;
  148. return -1;
  149. } else if (ret < 0) {
  150. errno = EINVAL;
  151. return -1;
  152. }
  153. offset += ret;
  154. }
  155. return offset;
  156. }
  157. int io_channel_send(QIOChannel *ioc, const void *buf, size_t len)
  158. {
  159. return io_channel_send_full(ioc, buf, len, NULL, 0);
  160. }