struct virConsoleBuffer terminalToStream;
char escapeChar;
+ virError error;
};
static virClassPtr virConsoleClass;
static void
virConsoleShutdown(virConsolePtr con)
{
+ virErrorPtr err = virGetLastError();
+
+ if (con->error.code == VIR_ERR_OK && err)
+ virCopyLastError(&con->error);
+
if (con->st) {
virStreamEventRemoveCallback(con->st);
virStreamAbort(con->st);
virStreamFree(con->st);
virCondDestroy(&con->cond);
+ virResetError(&con->error);
}
if (got == -2)
goto cleanup; /* blocking */
if (got <= 0) {
+ if (got == 0)
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("console stream EOF"));
+
virConsoleShutdown(con);
goto cleanup;
}
con->terminalToStream.offset,
avail);
if (got < 0) {
- if (errno != EAGAIN)
+ if (errno != EAGAIN) {
+ virReportSystemError(errno, "%s", _("cannot read from stdin"));
virConsoleShutdown(con);
+ }
goto cleanup;
}
if (got == 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("EOF on stdin"));
virConsoleShutdown(con);
goto cleanup;
}
VIR_STREAM_EVENT_WRITABLE);
}
- if (events & VIR_EVENT_HANDLE_ERROR ||
- events & VIR_EVENT_HANDLE_HANGUP) {
+ if (events & VIR_EVENT_HANDLE_ERROR) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("IO error on stdin"));
virConsoleShutdown(con);
+ goto cleanup;
+ }
+
+ if (events & VIR_EVENT_HANDLE_HANGUP) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("EOF on stdin"));
+ virConsoleShutdown(con);
+ goto cleanup;
}
cleanup:
con->streamToTerminal.data,
con->streamToTerminal.offset);
if (done < 0) {
- if (errno != EAGAIN)
+ if (errno != EAGAIN) {
+ virReportSystemError(errno, "%s", _("cannot write to stdout"));
virConsoleShutdown(con);
+ }
goto cleanup;
}
memmove(con->streamToTerminal.data,
if (!con->streamToTerminal.offset)
virEventUpdateHandle(con->stdoutWatch, 0);
- if (events & VIR_EVENT_HANDLE_ERROR ||
- events & VIR_EVENT_HANDLE_HANGUP) {
+ if (events & VIR_EVENT_HANDLE_ERROR) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("IO error stdout"));
virConsoleShutdown(con);
+ goto cleanup;
+ }
+
+ if (events & VIR_EVENT_HANDLE_HANGUP) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("EOF on stdout"));
+ virConsoleShutdown(con);
+ goto cleanup;
}
cleanup:
while (!con->quit) {
if (virCondWait(&con->cond, &con->parent.lock) < 0) {
- VIR_ERROR(_("unable to wait on console condition"));
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("unable to wait on console condition"));
goto cleanup;
}
}
- ret = 0;
+ if (con->error.code == VIR_ERR_OK)
+ ret = 0;
cleanup:
virConsoleShutdown(con);
+
+ if (ret < 0) {
+ vshResetLibvirtError();
+ virSetError(&con->error);
+ vshSaveLibvirtHelperError();
+ }
+
virObjectUnlock(con);
virObjectUnref(con);