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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list