static gboolean do_console_raw_local_read(GObject *stream, gpointer opaque) { GUnixInputStream *localStdin = G_UNIX_INPUT_STREAM(stream); GVirSandboxConsoleRaw *console = GVIR_SANDBOX_CONSOLE_RAW(opaque); GVirSandboxConsoleRawPrivate *priv = console->priv; GError *err = NULL; gssize ret = g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM(localStdin), priv->localToConsole + priv->localToConsoleOffset, priv->localToConsoleLength - priv->localToConsoleOffset, NULL, &err); if (ret < 0) { g_debug("Error from local read %s", err ? err->message : ""); do_console_raw_close(console, err); g_error_free(err); goto cleanup; } if (ret == 0) priv->localEOF = TRUE; else if (priv->localToConsole[priv->localToConsoleOffset] == CONTROL(gvir_sandbox_console_get_escape(GVIR_SANDBOX_CONSOLE(console)))) { do_console_raw_close(console, err); goto cleanup; } priv->localToConsoleOffset += ret; priv->localStdinSource = NULL; do_console_raw_update_events(console); cleanup: return FALSE; }
static void gvir_sandbox_console_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GVirSandboxConsole *console = GVIR_SANDBOX_CONSOLE(object); GVirSandboxConsolePrivate *priv = console->priv; switch (prop_id) { case PROP_CONNECTION: g_value_set_object(value, priv->connection); break; case PROP_DOMAIN: g_value_set_object(value, priv->domain); break; case PROP_DEVNAME: g_value_set_string(value, priv->devname); break; case PROP_ESCAPE: g_value_set_schar(value, priv->escape); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); } }
static void gvir_sandbox_console_raw_finalize(GObject *object) { GVirSandboxConsoleRaw *console = GVIR_SANDBOX_CONSOLE_RAW(object); GVirSandboxConsoleRawPrivate *priv = console->priv; if (priv->attached) gvir_sandbox_console_detach(GVIR_SANDBOX_CONSOLE(console), NULL); /* All other private fields are free'd by the detach call */ G_OBJECT_CLASS(gvir_sandbox_console_raw_parent_class)->finalize(object); }
static void gvir_sandbox_console_finalize(GObject *object) { GVirSandboxConsole *console = GVIR_SANDBOX_CONSOLE(object); GVirSandboxConsolePrivate *priv = console->priv; if (priv->domain) g_object_unref(priv->domain); if (priv->connection) g_object_unref(priv->connection); g_free(priv->devname); G_OBJECT_CLASS(gvir_sandbox_console_parent_class)->finalize(object); }
static gboolean gvir_sandbox_console_open_remote(GVirSandboxConsoleRaw *console, GError **error) { GVirSandboxConsoleRawPrivate *priv = console->priv; GVirConnection *conn = NULL; GVirDomain *dom = NULL; gchar *devname = NULL; gboolean ret = FALSE; GVirConfigDomain *conf = NULL; GList *devices = NULL, *tmp; g_object_get(console, "connection", &conn, "domain", &dom, "devname", &devname, NULL); if (!gvir_sandbox_console_get_direct(GVIR_SANDBOX_CONSOLE(console))) { priv->console = gvir_connection_get_stream(conn, 0); if (!gvir_domain_open_console(dom, priv->console, devname, 0, error)) { g_object_unref(priv->console); priv->console = NULL; goto cleanup; } } else { const gchar *pty = NULL; if (!(conf = gvir_domain_get_config(dom, 0, error))) goto cleanup; if (!(devices = gvir_config_domain_get_devices(conf))) { g_set_error(error, GVIR_SANDBOX_CONSOLE_RAW_ERROR, 0, "%s", _("No devices found for domain")); goto cleanup; } tmp = devices; while (tmp && !pty) { GVirConfigDomainDevice *dev = tmp->data; const gchar *alias = gvir_config_domain_device_get_alias(dev); if (alias && g_str_equal(alias, devname) && GVIR_CONFIG_IS_DOMAIN_CHARDEV(dev)) { GVirConfigDomainChardev *cdev = GVIR_CONFIG_DOMAIN_CHARDEV(dev); GVirConfigDomainChardevSource *csrc = gvir_config_domain_chardev_get_source(cdev); if (GVIR_CONFIG_IS_DOMAIN_CHARDEV_SOURCE_PTY(csrc)) { GVirConfigDomainChardevSourcePty *csrcpty = GVIR_CONFIG_DOMAIN_CHARDEV_SOURCE_PTY(csrc); pty = gvir_config_domain_chardev_source_pty_get_path(csrcpty); break; } } tmp = tmp->next; } if (!pty) { g_set_error(error, GVIR_SANDBOX_CONSOLE_RAW_ERROR, 0, _("No device %s found for domain"), devname); goto cleanup; } if ((priv->consolePty = open(pty, O_NOCTTY|O_RDWR)) < 0) { g_set_error(error, GVIR_SANDBOX_CONSOLE_RAW_ERROR, 0, _("Unable to open console %s"), pty); goto cleanup; } priv->consoleInput = G_UNIX_INPUT_STREAM(g_unix_input_stream_new(priv->consolePty, FALSE)); priv->consoleOutput = G_UNIX_OUTPUT_STREAM(g_unix_output_stream_new(priv->consolePty, FALSE)); } ret = TRUE; cleanup: if (conf) g_object_unref(conf); if (conn) g_object_unref(conn); if (dom) g_object_unref(dom); g_free(devname); return ret; }
static void do_console_raw_close(GVirSandboxConsoleRaw *console, GError *error) { gvir_sandbox_console_detach(GVIR_SANDBOX_CONSOLE(console), NULL); g_signal_emit_by_name(console, "closed", error != NULL); }