From ebef68936396f7eab077e883ac48c4ce0508afa2 Mon Sep 17 00:00:00 2001 From: Peter Krempa <pkrempa@redhat.com> Date: Thu, 29 Aug 2013 10:36:00 +0200 Subject: [PATCH] virsh: Remember terminal state when starting and add helpers 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 | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.h | 9 +++++++++ 2 files changed, 63 insertions(+) diff --git a/tools/virsh.c b/tools/virsh.c index 38345c0f3a..2f04e6a695 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -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; diff --git a/tools/virsh.h b/tools/virsh.h index 570d6a9943..db5934f99a 100644 --- a/tools/virsh.h +++ b/tools/virsh.h @@ -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__) -- GitLab