int vshRunConsole(virDomainPtr dom, const char *dev_name, const char *escape_seq, unsigned int flags) { int ret = -1; struct termios ttyattr; void (*old_sigquit)(int); void (*old_sigterm)(int); void (*old_sigint)(int); void (*old_sighup)(int); void (*old_sigpipe)(int); virConsolePtr con = NULL; /* Put STDIN into raw mode so that stuff typed does not echo to the screen (the TTY reads will result in it being echoed back already), and also ensure Ctrl-C, etc is blocked, and misc other bits */ if (vshMakeStdinRaw(&ttyattr, true) < 0) goto resettty; /* Trap all common signals so that we can safely restore the original terminal settings on STDIN before the process exits - people don't like being left with a messed up terminal ! */ old_sigquit = signal(SIGQUIT, do_signal); old_sigterm = signal(SIGTERM, do_signal); old_sigint = signal(SIGINT, do_signal); old_sighup = signal(SIGHUP, do_signal); old_sigpipe = signal(SIGPIPE, do_signal); got_signal = 0; if (VIR_ALLOC(con) < 0) { virReportOOMError(); goto cleanup; } con->escapeChar = vshGetEscapeChar(escape_seq); con->st = virStreamNew(virDomainGetConnect(dom), VIR_STREAM_NONBLOCK); if (!con->st) goto cleanup; if (virDomainOpenConsole(dom, dev_name, con->st, flags) < 0) goto cleanup; if (virCondInit(&con->cond) < 0 || virMutexInit(&con->lock) < 0) goto cleanup; con->stdinWatch = virEventAddHandle(STDIN_FILENO, VIR_EVENT_HANDLE_READABLE, virConsoleEventOnStdin, con, NULL); con->stdoutWatch = virEventAddHandle(STDOUT_FILENO, 0, virConsoleEventOnStdout, con, NULL); virStreamEventAddCallback(con->st, VIR_STREAM_EVENT_READABLE, virConsoleEventOnStream, con, NULL); while (!con->quit) { if (virCondWait(&con->cond, &con->lock) < 0) { VIR_ERROR(_("unable to wait on console condition")); goto cleanup; } } ret = 0; cleanup: if (con) { if (con->st) virStreamFree(con->st); virMutexDestroy(&con->lock); ignore_value(virCondDestroy(&con->cond)); VIR_FREE(con); } /* Restore original signal handlers */ signal(SIGPIPE, old_sigpipe); signal(SIGHUP, old_sighup); signal(SIGINT, old_sigint); signal(SIGTERM, old_sigterm); signal(SIGQUIT, old_sigquit); resettty: /* Put STDIN back into the (sane?) state we found it in before starting */ tcsetattr(STDIN_FILENO, TCSAFLUSH, &ttyattr); return ret; }
int virshRunConsole(vshControl *ctl, virDomainPtr dom, const char *dev_name, unsigned int flags) { virConsolePtr con = NULL; virshControlPtr priv = ctl->privData; int ret = -1; struct sigaction old_sigquit; struct sigaction old_sigterm; struct sigaction old_sigint; struct sigaction old_sighup; struct sigaction old_sigpipe; struct sigaction sighandler = {.sa_handler = virConsoleHandleSignal, .sa_flags = SA_SIGINFO }; sigemptyset(&sighandler.sa_mask); /* Put STDIN into raw mode so that stuff typed does not echo to the screen * (the TTY reads will result in it being echoed back already), and also * ensure Ctrl-C, etc is blocked, and misc other bits */ if (vshTTYMakeRaw(ctl, true) < 0) goto resettty; if (!(con = virConsoleNew())) goto resettty; virObjectLock(con); /* Trap all common signals so that we can safely restore the original * terminal settings on STDIN before the process exits - people don't like * being left with a messed up terminal ! */ sigaction(SIGQUIT, &sighandler, &old_sigquit); sigaction(SIGTERM, &sighandler, &old_sigterm); sigaction(SIGINT, &sighandler, &old_sigint); sigaction(SIGHUP, &sighandler, &old_sighup); sigaction(SIGPIPE, &sighandler, &old_sigpipe); con->escapeChar = virshGetEscapeChar(priv->escapeChar); con->st = virStreamNew(virDomainGetConnect(dom), VIR_STREAM_NONBLOCK); if (!con->st) goto cleanup; if (virDomainOpenConsole(dom, dev_name, con->st, flags) < 0) goto cleanup; virObjectRef(con); if ((con->stdinWatch = virEventAddHandle(STDIN_FILENO, VIR_EVENT_HANDLE_READABLE, virConsoleEventOnStdin, con, virObjectFreeCallback)) < 0) { virObjectUnref(con); goto cleanup; } virObjectRef(con); if ((con->stdoutWatch = virEventAddHandle(STDOUT_FILENO, 0, virConsoleEventOnStdout, con, virObjectFreeCallback)) < 0) { virObjectUnref(con); goto cleanup; } virObjectRef(con); if (virStreamEventAddCallback(con->st, VIR_STREAM_EVENT_READABLE, virConsoleEventOnStream, con, virObjectFreeCallback) < 0) { virObjectUnref(con); goto cleanup; } while (!con->quit) { if (virCondWait(&con->cond, &con->parent.lock) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("unable to wait on console condition")); goto cleanup; } } if (con->error.code == VIR_ERR_OK) ret = 0; cleanup: virConsoleShutdown(con); if (ret < 0) { vshResetLibvirtError(); virSetError(&con->error); vshSaveLibvirtHelperError(); } virObjectUnlock(con); virObjectUnref(con); /* Restore original signal handlers */ sigaction(SIGQUIT, &old_sigquit, NULL); sigaction(SIGTERM, &old_sigterm, NULL); sigaction(SIGINT, &old_sigint, NULL); sigaction(SIGHUP, &old_sighup, NULL); sigaction(SIGPIPE, &old_sigpipe, NULL); resettty: /* Put STDIN back into the (sane?) state we found it in before starting */ vshTTYRestore(ctl); return ret; }
/** * @brief provides the uri used to access the domain * @return string containing the uri */ QString Domain::uri() { virConnectPtr conn = virDomainGetConnect(m_domain); return QString(virConnectGetURI(conn)); }