forked from Mirror/frr
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> (cherry picked from commit ba53a8fdecef07577dcc4109e5c82bb124d49c58)
This commit is contained in:
parent
b764292587
commit
b510a06e1f
37
lib/vty.c
37
lib/vty.c
|
@ -38,6 +38,7 @@
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
|
||||||
#include <arpa/telnet.h>
|
#include <arpa/telnet.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
/* Vty events */
|
/* Vty events */
|
||||||
enum event
|
enum event
|
||||||
|
@ -1701,12 +1702,30 @@ vty_create (int vty_sock, union sockunion *su)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create vty for stdio */
|
/* 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 *
|
struct vty *
|
||||||
vty_stdio (void)
|
vty_stdio (void)
|
||||||
{
|
{
|
||||||
struct vty *vty;
|
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;
|
vty->wfd = 1;
|
||||||
|
|
||||||
/* always have stdio vty in a known _unchangeable_ state, don't want config
|
/* always have stdio vty in a known _unchangeable_ state, don't want config
|
||||||
|
@ -1715,6 +1734,18 @@ vty_stdio (void)
|
||||||
vty->v_timeout = 0;
|
vty->v_timeout = 0;
|
||||||
strcpy (vty->address, "console");
|
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);
|
vty_prompt (vty);
|
||||||
|
|
||||||
/* Add read/write thread. */
|
/* Add read/write thread. */
|
||||||
|
@ -2226,6 +2257,8 @@ vty_close (struct vty *vty)
|
||||||
/* Close socket. */
|
/* Close socket. */
|
||||||
if (vty->fd > 0)
|
if (vty->fd > 0)
|
||||||
close (vty->fd);
|
close (vty->fd);
|
||||||
|
else
|
||||||
|
vty_stdio_reset ();
|
||||||
|
|
||||||
if (vty->buf)
|
if (vty->buf)
|
||||||
XFREE (MTYPE_VTY, vty->buf);
|
XFREE (MTYPE_VTY, vty->buf);
|
||||||
|
@ -3039,6 +3072,8 @@ vty_init (struct thread_master *master_thread)
|
||||||
|
|
||||||
vty_master = master_thread;
|
vty_master = master_thread;
|
||||||
|
|
||||||
|
atexit (vty_stdio_reset);
|
||||||
|
|
||||||
/* Initilize server thread vector. */
|
/* Initilize server thread vector. */
|
||||||
Vvty_serv_thread = vector_init (VECTOR_MIN_SIZE);
|
Vvty_serv_thread = vector_init (VECTOR_MIN_SIZE);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue