summaryrefslogtreecommitdiffstats
path: root/lib/vty.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2015-05-05 11:04:46 +0200
committerDavid Lamparter <equinox@opensourcerouting.org>2015-05-27 20:34:40 +0200
commitba53a8fdecef07577dcc4109e5c82bb124d49c58 (patch)
tree82b3cd36a4812e4f34baaeac106bb28ad0f49bb8 /lib/vty.c
parentba5dc5ebb4dba56cb3a64acc21e71aa34df375d9 (diff)
downloadquagga-ba53a8fdecef07577dcc4109e5c82bb124d49c58.tar.bz2
quagga-ba53a8fdecef07577dcc4109e5c82bb124d49c58.tar.xz
lib/vty: put stdin in raw mode for vty
The interactive CLI actually works just fine, if we just put the terminal in raw mode to get keystrokes as they come. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib/vty.c')
-rw-r--r--lib/vty.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/lib/vty.c b/lib/vty.c
index 24df32c4..a3f1a3c4 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -38,6 +38,7 @@
#include "network.h"
#include <arpa/telnet.h>
+#include <termios.h>
/* Vty events */
enum event
@@ -1700,12 +1701,30 @@ vty_create (int vty_sock, union sockunion *su)
}
/* create vty for stdio */
+static struct termios stdio_orig_termios;
+static struct vty *stdio_vty = NULL;
+
+static void
+vty_stdio_reset (void)
+{
+ if (stdio_vty)
+ {
+ tcsetattr (0, TCSANOW, &stdio_orig_termios);
+ stdio_vty = NULL;
+ }
+}
+
struct vty *
vty_stdio (void)
{
struct vty *vty;
+ struct termios termios;
- vty = vty_new_init (0);
+ /* refuse creating two vtys on stdio */
+ if (stdio_vty)
+ return NULL;
+
+ vty = stdio_vty = vty_new_init (0);
vty->wfd = 1;
/* always have stdio vty in a known _unchangeable_ state, don't want config
@@ -1714,6 +1733,18 @@ vty_stdio (void)
vty->v_timeout = 0;
strcpy (vty->address, "console");
+ if (!tcgetattr (0, &stdio_orig_termios))
+ {
+ termios = stdio_orig_termios;
+ termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
+ | INLCR | IGNCR | ICRNL | IXON);
+ termios.c_oflag &= ~OPOST;
+ termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+ termios.c_cflag &= ~(CSIZE | PARENB);
+ termios.c_cflag |= CS8;
+ tcsetattr (0, TCSANOW, &termios);
+ }
+
vty_prompt (vty);
/* Add read/write thread. */
@@ -2225,6 +2256,8 @@ vty_close (struct vty *vty)
/* Close socket. */
if (vty->fd > 0)
close (vty->fd);
+ else
+ vty_stdio_reset ();
if (vty->buf)
XFREE (MTYPE_VTY, vty->buf);
@@ -3004,6 +3037,8 @@ vty_init (struct thread_master *master_thread)
master = master_thread;
+ atexit (vty_stdio_reset);
+
/* Initilize server thread vector. */
Vvty_serv_thread = vector_init (VECTOR_MIN_SIZE);