]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virsh: Remember terminal state when starting and add helpers
authorPeter Krempa <pkrempa@redhat.com>
Thu, 29 Aug 2013 08:36:00 +0000 (10:36 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 3 Sep 2013 07:55:27 +0000 (09:55 +0200)
This patch adds instrumentation to allow modification of config of the
terminal in virsh and successful reset of the state afterwards.

The added helpers allow to disable receiving of SIGINT when pressing the
key sequence (Ctrl+C usualy). This normally sends SIGINT to the
foreground process group which kills ssh processes used for transport of
the data.

tools/virsh.c
tools/virsh.h

index 38345c0f3a3e2e4f82bde791cf21108ae97f1375..2f04e6a6951072f5263270c13ef8b67a09a9831a 100644 (file)
@@ -2213,6 +2213,53 @@ vshPrintExtra(vshControl *ctl, const char *format, ...)
 }
 
 
+bool
+vshTTYIsInterruptCharacter(vshControl *ctl,
+                           const char chr)
+{
+    if (ctl->istty &&
+        ctl->termattr.c_cc[VINTR] == chr)
+        return true;
+
+    return false;
+}
+
+
+int
+vshTTYDisableInterrupt(vshControl *ctl)
+{
+    struct termios termset = ctl->termattr;
+
+    if (!ctl->istty)
+        return -1;
+
+    /* check if we need to set the terminal */
+    if (termset.c_cc[VINTR] == _POSIX_VDISABLE)
+        return 0;
+
+    termset.c_cc[VINTR] = _POSIX_VDISABLE;
+    termset.c_lflag &= ~ICANON;
+
+    if (tcsetattr(STDIN_FILENO, TCSANOW, &termset) < 0)
+        return -1;
+
+    return 0;
+}
+
+
+int
+vshTTYRestore(vshControl *ctl)
+{
+    if (!ctl->istty)
+        return 0;
+
+    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &ctl->termattr) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 void
 vshError(vshControl *ctl, const char *format, ...)
 {
@@ -3157,6 +3204,13 @@ main(int argc, char **argv)
         return EXIT_FAILURE;
     }
 
+    if (isatty(STDIN_FILENO)) {
+        ctl->istty = true;
+
+        if (tcgetattr(STDIN_FILENO, &ctl->termattr) < 0)
+            ctl->istty = false;
+    }
+
     if (virMutexInit(&ctl->lock) < 0) {
         vshError(ctl, "%s", _("Failed to initialize mutex"));
         return EXIT_FAILURE;
index 570d6a994312ef69faf52877c23b5653cedc41d0..db5934f99abbc991d39b34413f7a88b2fc1c1ff6 100644 (file)
@@ -32,6 +32,7 @@
 # include <unistd.h>
 # include <sys/stat.h>
 # include <inttypes.h>
+# include <termios.h>
 
 # include "internal.h"
 # include "virerror.h"
@@ -240,6 +241,9 @@ struct _vshControl {
 
     const char *escapeChar;     /* String representation of
                                    console escape character */
+
+    struct termios termattr;    /* settings of the tty terminal */
+    bool istty;                 /* is the terminal a tty */
 };
 
 struct _vshCmdGrp {
@@ -350,6 +354,11 @@ void vshReportError(vshControl *ctl);
 void vshResetLibvirtError(void);
 void vshSaveLibvirtError(void);
 
+/* terminal modifications */
+bool vshTTYIsInterruptCharacter(vshControl *ctl, const char chr);
+int vshTTYDisableInterrupt(vshControl *ctl);
+int vshTTYRestore(vshControl *ctl);
+
 /* allocation wrappers */
 void *_vshMalloc(vshControl *ctl, size_t sz, const char *filename, int line);
 # define vshMalloc(_ctl, _sz)    _vshMalloc(_ctl, _sz, __FILE__, __LINE__)