static gboolean fd_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) { Chardev *chr = CHARDEV(opaque); FDChardev *s = FD_CHARDEV(opaque); int len; uint8_t buf[CHR_READ_BUF_LEN]; ssize_t ret; len = sizeof(buf); if (len > s->max_size) { len = s->max_size; } if (len == 0) { return TRUE; } ret = qio_channel_read( chan, (gchar *)buf, len, NULL); if (ret == 0) { remove_fd_in_watch(chr); qemu_chr_be_event(chr, CHR_EVENT_CLOSED); return FALSE; } if (ret > 0) { qemu_chr_be_write(chr, buf, ret); } return TRUE; }
/* Called with chr_write_lock held. */ static void pty_chr_state(Chardev *chr, int connected) { PtyChardev *s = PTY_CHARDEV(chr); if (!connected) { if (s->open_source) { g_source_destroy(s->open_source); g_source_unref(s->open_source); s->open_source = NULL; } remove_fd_in_watch(chr); s->connected = 0; /* (re-)connect poll interval for idle guests: once per second. * We check more frequently in case the guests sends data to * the virtual device linked to our pty. */ pty_chr_rearm_timer(chr, 1000); } else { pty_chr_timer_cancel(s); if (!s->connected) { g_assert(s->open_source == NULL); s->open_source = g_idle_source_new(); s->connected = 1; g_source_set_callback(s->open_source, qemu_chr_be_generic_open_func, chr, NULL); g_source_attach(s->open_source, chr->gcontext); } if (!chr->gsource) { chr->gsource = io_add_watch_poll(chr, s->ioc, pty_chr_read_poll, pty_chr_read, chr, chr->gcontext); } } }
static void tcp_chr_free_connection(Chardev *chr) { SocketChardev *s = SOCKET_CHARDEV(chr); int i; if (!s->connected) { return; } if (s->read_msgfds_num) { for (i = 0; i < s->read_msgfds_num; i++) { close(s->read_msgfds[i]); } g_free(s->read_msgfds); s->read_msgfds = NULL; s->read_msgfds_num = 0; } tcp_set_msgfds(chr, NULL, 0); remove_fd_in_watch(chr); object_unref(OBJECT(s->sioc)); s->sioc = NULL; object_unref(OBJECT(s->ioc)); s->ioc = NULL; g_free(chr->filename); chr->filename = NULL; s->connected = 0; }
static void pty_chr_state(Chardev *chr, int connected) { PtyChardev *s = PTY_CHARDEV(chr); if (!connected) { remove_fd_in_watch(chr); s->connected = 0; /* (re-)connect poll interval for idle guests: once per second. * We check more frequently in case the guests sends data to * the virtual device linked to our pty. */ pty_chr_rearm_timer(chr, 1000); } else { pty_chr_timer_cancel(s); if (!s->connected) { s->connected = 1; qemu_chr_be_event(chr, CHR_EVENT_OPENED); } if (!chr->gsource) { chr->gsource = io_add_watch_poll(chr, s->ioc, pty_chr_read_poll, pty_chr_read, chr, chr->gcontext); } } }
static void char_udp_finalize(Object *obj) { Chardev *chr = CHARDEV(obj); UdpChardev *s = UDP_CHARDEV(obj); remove_fd_in_watch(chr); if (s->ioc) { object_unref(OBJECT(s->ioc)); } qemu_chr_be_event(chr, CHR_EVENT_CLOSED); }
static void udp_chr_update_read_handler(Chardev *chr) { UdpChardev *s = UDP_CHARDEV(chr); remove_fd_in_watch(chr); if (s->ioc) { chr->gsource = io_add_watch_poll(chr, s->ioc, udp_chr_read_poll, udp_chr_read, chr, chr->gcontext); } }
static void fd_chr_update_read_handler(Chardev *chr, GMainContext *context) { FDChardev *s = FD_CHARDEV(chr); remove_fd_in_watch(chr); if (s->ioc_in) { chr->gsource = io_add_watch_poll(chr, s->ioc_in, fd_chr_read_poll, fd_chr_read, chr, context); } }
static void udp_chr_update_read_handler(Chardev *chr, GMainContext *context) { UdpChardev *s = UDP_CHARDEV(chr); remove_fd_in_watch(chr, NULL); if (s->ioc) { chr->fd_in_tag = io_add_watch_poll(chr, s->ioc, udp_chr_read_poll, udp_chr_read, chr, context); } }
static void char_fd_finalize(Object *obj) { Chardev *chr = CHARDEV(obj); FDChardev *s = FD_CHARDEV(obj); remove_fd_in_watch(chr); if (s->ioc_in) { object_unref(OBJECT(s->ioc_in)); } if (s->ioc_out) { object_unref(OBJECT(s->ioc_out)); } qemu_chr_be_event(chr, CHR_EVENT_CLOSED); }
static void tcp_chr_update_read_handler(Chardev *chr, GMainContext *context) { SocketChardev *s = SOCKET_CHARDEV(chr); if (!s->connected) { return; } remove_fd_in_watch(chr); if (s->ioc) { chr->fd_in_tag = io_add_watch_poll(chr, s->ioc, tcp_chr_read_poll, tcp_chr_read, chr, context); } }
static gboolean udp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque) { Chardev *chr = CHARDEV(opaque); UdpChardev *s = UDP_CHARDEV(opaque); ssize_t ret; if (s->max_size == 0) { return TRUE; } ret = qio_channel_read( s->ioc, (char *)s->buf, sizeof(s->buf), NULL); if (ret <= 0) { remove_fd_in_watch(chr); return FALSE; } s->bufcnt = ret; s->bufptr = 0; udp_chr_flush_buffer(s); return TRUE; }