static gboolean gvir_sandbox_console_raw_detach(GVirSandboxConsole *console,
                                                GError **error)
{
    GVirSandboxConsoleRawPrivate *priv = GVIR_SANDBOX_CONSOLE_RAW(console)->priv;
    gboolean ret = FALSE;
    if (!priv->console) {
        return TRUE;
#if 0
        g_set_error(error, GVIR_SANDBOX_CONSOLE_RAW_ERROR, 0, "%s",
                    _("Console is not attached to a stream"));
        return FALSE;
#endif
    }

    if (priv->localStdin &&
        !gvir_sandbox_console_raw_stop_term(GVIR_SANDBOX_CONSOLE_RAW(console),
                                            priv->localStdin, error))
        return FALSE;

    if (priv->console) {
        g_object_unref(priv->console);
        priv->console = NULL;
        priv->consoleToLocalOffset = priv->consoleToLocalLength = 0;
        priv->localToConsoleOffset = priv->localToConsoleLength = 0;
        g_free(priv->consoleToLocal);
        g_free(priv->localToConsole);
        priv->consoleToLocal = priv->localToConsole = NULL;
    }

    if (priv->localStdinSource)
        g_source_unref(priv->localStdinSource);
    if (priv->localStdoutSource)
        g_source_unref(priv->localStdoutSource);
    if (priv->localStderrSource)
        g_source_unref(priv->localStderrSource);
    if (priv->consoleWatch)
        g_source_remove(priv->consoleWatch);
    priv->localStdinSource = priv->localStdoutSource = priv->localStderrSource = NULL;
    priv->consoleWatch = 0;

    if (priv->localStdin)
        g_object_unref(priv->localStdin);
    if (priv->localStdout)
        g_object_unref(priv->localStdout);
    g_object_unref(priv->localStderr);
    priv->localStdin = NULL;
    priv->localStdout = NULL;
    priv->localStderr = NULL;

    ret = TRUE;

//cleanup:
    return ret;
}
static gboolean gvir_sandbox_console_raw_attach(GVirSandboxConsole *console,
                                                GUnixInputStream *localStdin,
                                                GUnixOutputStream *localStdout,
                                                GUnixOutputStream *localStderr,
                                                GError **error)
{
    GVirSandboxConsoleRawPrivate *priv = GVIR_SANDBOX_CONSOLE_RAW(console)->priv;
    gboolean ret = FALSE;

    if (priv->attached) {
        g_set_error(error, GVIR_SANDBOX_CONSOLE_RAW_ERROR, 0, "%s",
                    _("Console is already attached to a stream"));
        return FALSE;
    }

    if (localStdin &&
        !gvir_sandbox_console_raw_start_term(GVIR_SANDBOX_CONSOLE_RAW(console),
                                             localStdin, error))
        return FALSE;

    priv->localStdin = localStdin ? g_object_ref(localStdin) : NULL;
    priv->localStdout = localStdout ? g_object_ref(localStdout) : NULL;
    priv->localStderr = g_object_ref(localStderr);

    if (!gvir_sandbox_console_open_remote(GVIR_SANDBOX_CONSOLE_RAW(console),
                                          error))
        goto cleanup;

    priv->consoleToLocalLength = 4096;
    priv->consoleToLocal = g_new0(gchar, priv->consoleToLocalLength);
    if (localStdin) {
        priv->localToConsoleLength = 4096;
        priv->localToConsole = g_new0(gchar, priv->localToConsoleLength);
    }

    priv->attached = TRUE;

    do_console_raw_update_events(GVIR_SANDBOX_CONSOLE_RAW(console));

    ret = TRUE;
 cleanup:
    if (!ret && localStdin)
        gvir_sandbox_console_raw_stop_term(GVIR_SANDBOX_CONSOLE_RAW(console),
                                           localStdin, NULL);

    return ret;
}
static gboolean gvir_sandbox_console_raw_detach(GVirSandboxConsole *console,
                                                GError **error)
{
    GVirSandboxConsoleRawPrivate *priv = GVIR_SANDBOX_CONSOLE_RAW(console)->priv;
    gboolean ret = FALSE;

    if (!priv->attached)
        return TRUE;

    if (priv->localStdin &&
        !gvir_sandbox_console_raw_stop_term(GVIR_SANDBOX_CONSOLE_RAW(console),
                                            priv->localStdin, error))
        return FALSE;

    priv->consoleToLocalOffset = priv->consoleToLocalLength = 0;
    priv->localToConsoleOffset = priv->localToConsoleLength = 0;
    g_free(priv->consoleToLocal);
    g_free(priv->localToConsole);
    priv->consoleToLocal = priv->localToConsole = NULL;

    if (priv->localStdinSource)
        g_source_unref(priv->localStdinSource);
    if (priv->localStdoutSource)
        g_source_unref(priv->localStdoutSource);
    if (priv->localStderrSource)
        g_source_unref(priv->localStderrSource);
    if (priv->consoleWatch)
        g_source_remove(priv->consoleWatch);
    if (priv->consoleInputSource)
        g_source_unref(priv->consoleInputSource);
    if (priv->consoleOutputSource)
        g_source_unref(priv->consoleOutputSource);

    priv->localStdinSource = priv->localStdoutSource = priv->localStderrSource = NULL;
    priv->consoleWatch = 0;
    priv->consoleInputSource = priv->consoleOutputSource = NULL;


    if (priv->console) {
        g_object_unref(priv->console);
        priv->console = NULL;
    }
    if (priv->consoleInput) {
        g_object_unref(priv->consoleInput);
        priv->consoleInput = NULL;
    }
    if (priv->consoleOutput) {
        g_object_unref(priv->consoleOutput);
        priv->consoleOutput = NULL;
    }

    if (priv->localStdin)
        g_object_unref(priv->localStdin);
    if (priv->localStdout)
        g_object_unref(priv->localStdout);
    g_object_unref(priv->localStderr);
    priv->localStdin = NULL;
    priv->localStdout = NULL;
    priv->localStderr = NULL;

    priv->attached = FALSE;

    ret = TRUE;

    //cleanup:
    return ret;
}
static gboolean gvir_sandbox_console_raw_attach(GVirSandboxConsole *console,
                                                GUnixInputStream *localStdin,
                                                GUnixOutputStream *localStdout,
                                                GUnixOutputStream *localStderr,
                                                GError **error)
{
    GVirSandboxConsoleRawPrivate *priv = GVIR_SANDBOX_CONSOLE_RAW(console)->priv;
    gboolean ret = FALSE;
    GVirConnection *conn = NULL;
    GVirDomain *dom = NULL;
    gchar *devname = NULL;

    if (priv->console) {
        g_set_error(error, GVIR_SANDBOX_CONSOLE_RAW_ERROR, 0, "%s",
                    _("Console is already attached to a stream"));
        return FALSE;
    }

    if (localStdin &&
        !gvir_sandbox_console_raw_start_term(GVIR_SANDBOX_CONSOLE_RAW(console),
                                             localStdin, error))
        return FALSE;

    priv->localStdin = localStdin ? g_object_ref(localStdin) : NULL;
    priv->localStdout = localStdout ? g_object_ref(localStdout) : NULL;
    priv->localStderr = g_object_ref(localStderr);

    g_object_get(console,
                 "connection", &conn,
                 "domain", &dom,
                 "devname", &devname,
                 NULL);

    priv->console = gvir_connection_get_stream(conn, 0);

    if (!gvir_domain_open_console(dom, priv->console,
                                  devname, 0, error))
        goto cleanup;

    priv->consoleToLocalLength = 4096;
    priv->consoleToLocal = g_new0(gchar, priv->consoleToLocalLength);
    if (localStdin) {
        priv->localToConsoleLength = 4096;
        priv->localToConsole = g_new0(gchar, priv->localToConsoleLength);
    }

    do_console_raw_update_events(GVIR_SANDBOX_CONSOLE_RAW(console));

    ret = TRUE;
cleanup:
    if (!ret && localStdin)
        gvir_sandbox_console_raw_stop_term(GVIR_SANDBOX_CONSOLE_RAW(console),
                                           localStdin, NULL);

    if (conn)
        g_object_unref(conn);
    if (dom)
        g_object_unref(dom);
    g_free(devname);
    return ret;
}