/* false return signals GAChannel to close the current client connection */ static gboolean channel_event_cb(GIOCondition condition, gpointer data) { GAState *s = data; gchar buf[QGA_READ_COUNT_DEFAULT+1]; gsize count; GIOStatus status = ga_channel_read(s->channel, buf, QGA_READ_COUNT_DEFAULT, &count); switch (status) { case G_IO_STATUS_ERROR: g_warning("error reading channel"); return false; case G_IO_STATUS_NORMAL: buf[count] = 0; g_debug("read data, count: %d, data: %s", (int)count, buf); json_message_parser_feed(&s->parser, (char *)buf, (int)count); break; case G_IO_STATUS_EOF: g_debug("received EOF"); if (!s->virtio) { return false; } /* fall through */ case G_IO_STATUS_AGAIN: /* virtio causes us to spin here when no process is attached to * host-side chardev. sleep a bit to mitigate this */ if (s->virtio) { usleep(100*1000); } return true; default: g_warning("unknown channel read status, closing"); return false; } return true; }
QObject *qobject_from_jsonv(const char *string, va_list *ap) { JSONParsingState state = {}; state.ap = ap; json_message_parser_init(&state.parser, parse_json); json_message_parser_feed(&state.parser, string, strlen(string)); json_message_parser_flush(&state.parser); json_message_parser_destroy(&state.parser); return state.result; }
static gboolean conn_channel_read(GIOChannel *channel, GIOCondition condition, gpointer data) { GAState *s = data; gchar buf[1024]; gsize count; GError *err = NULL; memset(buf, 0, 1024); GIOStatus status = g_io_channel_read_chars(channel, buf, 1024, &count, &err); if (err != NULL) { g_warning("error reading channel: %s", err->message); conn_channel_close(s); g_error_free(err); return false; } switch (status) { case G_IO_STATUS_ERROR: g_warning("problem"); return false; case G_IO_STATUS_NORMAL: g_debug("read data, count: %d, data: %s", (int)count, buf); json_message_parser_feed(&s->parser, (char *)buf, (int)count); case G_IO_STATUS_AGAIN: /* virtio causes us to spin here when no process is attached to * host-side chardev. sleep a bit to mitigate this */ if (s->virtio) { usleep(100*1000); } return true; case G_IO_STATUS_EOF: g_debug("received EOF"); conn_channel_close(s); if (s->virtio) { return true; } return false; default: g_warning("unknown channel read status, closing"); conn_channel_close(s); return false; } return true; }