If users *-edit but make a mistake in XML all changes are
permanently lost. However, if virsh is not running within
a script we can as user if he wants to re-edit the file
and correct the mistakes.
---
tools/console.c | 40 +++++++++++++++++++++++++---------------
tools/console.h | 2 ++
tools/virsh-edit.c | 8 +++++++-
tools/virsh.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 79 insertions(+), 16 deletions(-)
diff --git a/tools/console.c b/tools/console.c
index 34fde05..90e54e3 100644
--- a/tools/console.c
+++ b/tools/console.c
@@ -298,13 +298,36 @@ vshGetEscapeChar(const char *s)
return *s;
}
+int vshMakeStdinRaw(struct termios *ttyattr, bool report_errors) {
+ struct termios rawattr;
+
+ if (tcgetattr(STDIN_FILENO, ttyattr) < 0) {
+ if (report_errors)
+ VIR_ERROR(_("unable to get tty attributes: %s"),
+ strerror(errno));
+ return -1;
+ }
+
+ rawattr = *ttyattr;
+ cfmakeraw(&rawattr);
+
+ if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &rawattr) < 0) {
+ if (report_errors)
+ VIR_ERROR(_("unable to set tty attributes: %s"),
+ strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
int vshRunConsole(virDomainPtr dom,
const char *dev_name,
const char *escape_seq,
unsigned int flags)
{
int ret = -1;
- struct termios ttyattr, rawattr;
+ struct termios ttyattr;
void (*old_sigquit)(int);
void (*old_sigterm)(int);
void (*old_sigint)(int);
@@ -317,21 +340,8 @@ int vshRunConsole(virDomainPtr dom,
result in it being echoed back already), and
also ensure Ctrl-C, etc is blocked, and misc
other bits */
- if (tcgetattr(STDIN_FILENO, &ttyattr) < 0) {
- VIR_ERROR(_("unable to get tty attributes: %s"),
- strerror(errno));
- return -1;
- }
-
- rawattr = ttyattr;
- cfmakeraw(&rawattr);
-
- if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &rawattr) < 0) {
- VIR_ERROR(_("unable to set tty attributes: %s"),
- strerror(errno));
+ 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
diff --git a/tools/console.h b/tools/console.h
index 2b5440c..1feea9e 100644
--- a/tools/console.h
+++ b/tools/console.h
@@ -30,6 +30,8 @@ int vshRunConsole(virDomainPtr dom,
const char *escape_seq,
unsigned int flags);
+int vshMakeStdinRaw(struct termios *ttyattr, bool report_errors);
+
# endif /* !WIN32 */
#endif /* __VIR_CONSOLE_H__ */
diff --git a/tools/virsh-edit.c b/tools/virsh-edit.c
index 060dc14..d618bfa 100644
--- a/tools/virsh-edit.c
+++ b/tools/virsh-edit.c
@@ -14,6 +14,7 @@ do {
if (!tmp)
goto edit_cleanup;
+reedit:
/* Start the editor. */
if (editFile (ctl, tmp) == -1)
goto edit_cleanup;
@@ -45,8 +46,13 @@ do {
}
/* Everything checks out, so redefine the domain. */
- if (!(EDIT_DEFINE))
+ if (!(EDIT_DEFINE)) {
+ /* Redefine failed. If we are not running within
+ * a script ask used if he wants to re-edit the XML */
+ if (vshAskReedit(ctl) > 0)
+ goto reedit;
goto edit_cleanup;
+ }
goto edit_continue;
diff --git a/tools/virsh.c b/tools/virsh.c
index fb8ede4..4cb2013 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -33,6 +33,7 @@
#include <signal.h>
#include <poll.h>
#include <strings.h>
+#include <termios.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
@@ -654,6 +655,50 @@ vshReconnect(vshControl *ctl)
ctl->useSnapshotOld = false;
}
+/**
+ * vshAskReedit:
+ *
+ * Ask user if he wants to return to previously
+ * edited file.
+ *
+ * Returns 1 if he wants to
+ * 0 if he doesn't want to
+ * -1 on error
+ */
+static int
+vshAskReedit(vshControl *ctl)
+{
+ int ret = 0;
+ int c = 0;
+ struct termios ttyattr;
+
+ if (!isatty(STDIN_FILENO))
+ return -1;
+
+ virshReportError(ctl);
+
+ if (vshMakeStdinRaw(&ttyattr, false) < 0)
+ return -1;
+
+ while (true) {
+ vshPrint(ctl, "\rFailed. Try again? (y/Y/n/N) [Y]:");
+ c = getchar();
+ c = c_toupper(c);
+ if (c == '\n' || c == '\r' || c == 'Y' || c ==
'N')
+ break;
+ }
+
+ tcsetattr(STDIN_FILENO, TCSAFLUSH, &ttyattr);
+
+ if (c == 'N')
+ goto cleanup;
+
+ ret = 1;
+cleanup:
+ vshPrint(ctl, "\r\n");
+ return ret;
+}
+
/* ---------------
* Commands
* ---------------
--
1.7.8.5