mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-06-14 11:32:30 +00:00
lib/vty: add separate output fd support to VTYs
to be used with stdin/stdout terminals, this adds support for writing to a different FD than we're reading from. Also fixes error messages from config load being written to stdin. [v2: fixed config write] Signed-off-by: David Lamparter <equinox@opensourcerouting.org> (cherry picked from commit 4715a53b4d390e72a06c864a6a505971841e3dc9)
This commit is contained in:
parent
dfa251d162
commit
c5e69a025f
@ -3153,7 +3153,7 @@ DEFUN (config_write_file,
|
|||||||
|
|
||||||
/* Make vty for configuration file. */
|
/* Make vty for configuration file. */
|
||||||
file_vty = vty_new ();
|
file_vty = vty_new ();
|
||||||
file_vty->fd = fd;
|
file_vty->wfd = fd;
|
||||||
file_vty->type = VTY_FILE;
|
file_vty->type = VTY_FILE;
|
||||||
|
|
||||||
/* Config file header print. */
|
/* Config file header print. */
|
||||||
|
27
lib/vty.c
27
lib/vty.c
@ -184,7 +184,7 @@ vty_log_out (struct vty *vty, const char *level, const char *proto_str,
|
|||||||
buf[len++] = '\r';
|
buf[len++] = '\r';
|
||||||
buf[len++] = '\n';
|
buf[len++] = '\n';
|
||||||
|
|
||||||
if (write(vty->fd, buf, len) < 0)
|
if (write(vty->wfd, buf, len) < 0)
|
||||||
{
|
{
|
||||||
if (ERRNO_IO_RETRY(errno))
|
if (ERRNO_IO_RETRY(errno))
|
||||||
/* Kernel buffer is full, probably too much debugging output, so just
|
/* Kernel buffer is full, probably too much debugging output, so just
|
||||||
@ -1543,7 +1543,7 @@ vty_read (struct thread *thread)
|
|||||||
vty_close (vty);
|
vty_close (vty);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vty_event (VTY_WRITE, vty_sock, vty);
|
vty_event (VTY_WRITE, vty->wfd, vty);
|
||||||
vty_event (VTY_READ, vty_sock, vty);
|
vty_event (VTY_READ, vty_sock, vty);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -1572,12 +1572,12 @@ vty_flush (struct thread *thread)
|
|||||||
|
|
||||||
/* N.B. if width is 0, that means we don't know the window size. */
|
/* N.B. if width is 0, that means we don't know the window size. */
|
||||||
if ((vty->lines == 0) || (vty->width == 0))
|
if ((vty->lines == 0) || (vty->width == 0))
|
||||||
flushrc = buffer_flush_available(vty->obuf, vty->fd);
|
flushrc = buffer_flush_available(vty->obuf, vty_sock);
|
||||||
else if (vty->status == VTY_MORELINE)
|
else if (vty->status == VTY_MORELINE)
|
||||||
flushrc = buffer_flush_window(vty->obuf, vty->fd, vty->width,
|
flushrc = buffer_flush_window(vty->obuf, vty_sock, vty->width,
|
||||||
1, erase, 0);
|
1, erase, 0);
|
||||||
else
|
else
|
||||||
flushrc = buffer_flush_window(vty->obuf, vty->fd, vty->width,
|
flushrc = buffer_flush_window(vty->obuf, vty_sock, vty->width,
|
||||||
vty->lines >= 0 ? vty->lines :
|
vty->lines >= 0 ? vty->lines :
|
||||||
vty->height,
|
vty->height,
|
||||||
erase, 0);
|
erase, 0);
|
||||||
@ -1623,6 +1623,7 @@ vty_create (int vty_sock, union sockunion *su)
|
|||||||
/* Allocate new vty structure and set up default values. */
|
/* Allocate new vty structure and set up default values. */
|
||||||
vty = vty_new ();
|
vty = vty_new ();
|
||||||
vty->fd = vty_sock;
|
vty->fd = vty_sock;
|
||||||
|
vty->wfd = vty_sock;
|
||||||
vty->type = VTY_TERM;
|
vty->type = VTY_TERM;
|
||||||
strcpy (vty->address, buf);
|
strcpy (vty->address, buf);
|
||||||
if (no_password_check)
|
if (no_password_check)
|
||||||
@ -2023,6 +2024,7 @@ vtysh_accept (struct thread *thread)
|
|||||||
|
|
||||||
vty = vty_new ();
|
vty = vty_new ();
|
||||||
vty->fd = sock;
|
vty->fd = sock;
|
||||||
|
vty->wfd = sock;
|
||||||
vty->type = VTY_SHELL_SERV;
|
vty->type = VTY_SHELL_SERV;
|
||||||
vty->node = VIEW_NODE;
|
vty->node = VIEW_NODE;
|
||||||
|
|
||||||
@ -2034,10 +2036,10 @@ vtysh_accept (struct thread *thread)
|
|||||||
static int
|
static int
|
||||||
vtysh_flush(struct vty *vty)
|
vtysh_flush(struct vty *vty)
|
||||||
{
|
{
|
||||||
switch (buffer_flush_available(vty->obuf, vty->fd))
|
switch (buffer_flush_available(vty->obuf, vty->wfd))
|
||||||
{
|
{
|
||||||
case BUFFER_PENDING:
|
case BUFFER_PENDING:
|
||||||
vty_event(VTYSH_WRITE, vty->fd, vty);
|
vty_event(VTYSH_WRITE, vty->wfd, vty);
|
||||||
break;
|
break;
|
||||||
case BUFFER_ERROR:
|
case BUFFER_ERROR:
|
||||||
vty->monitor = 0; /* disable monitoring to avoid infinite recursion */
|
vty->monitor = 0; /* disable monitoring to avoid infinite recursion */
|
||||||
@ -2173,7 +2175,7 @@ vty_close (struct vty *vty)
|
|||||||
thread_cancel (vty->t_timeout);
|
thread_cancel (vty->t_timeout);
|
||||||
|
|
||||||
/* Flush buffer. */
|
/* Flush buffer. */
|
||||||
buffer_flush_all (vty->obuf, vty->fd);
|
buffer_flush_all (vty->obuf, vty->wfd);
|
||||||
|
|
||||||
/* Free input buffer. */
|
/* Free input buffer. */
|
||||||
buffer_free (vty->obuf);
|
buffer_free (vty->obuf);
|
||||||
@ -2233,12 +2235,13 @@ vty_read_file (FILE *confp)
|
|||||||
unsigned int line_num = 0;
|
unsigned int line_num = 0;
|
||||||
|
|
||||||
vty = vty_new ();
|
vty = vty_new ();
|
||||||
vty->fd = dup(STDERR_FILENO); /* vty_close() will close this */
|
vty->wfd = dup(STDERR_FILENO); /* vty_close() will close this */
|
||||||
if (vty->fd < 0)
|
if (vty->wfd < 0)
|
||||||
{
|
{
|
||||||
/* Fine, we couldn't make a new fd. vty_close doesn't close stdout. */
|
/* Fine, we couldn't make a new fd. vty_close doesn't close stdout. */
|
||||||
vty->fd = STDOUT_FILENO;
|
vty->wfd = STDOUT_FILENO;
|
||||||
}
|
}
|
||||||
|
vty->fd = STDIN_FILENO;
|
||||||
vty->type = VTY_FILE;
|
vty->type = VTY_FILE;
|
||||||
vty->node = CONFIG_NODE;
|
vty->node = CONFIG_NODE;
|
||||||
|
|
||||||
@ -2493,7 +2496,7 @@ vty_log_fixed (char *buf, size_t len)
|
|||||||
if (((vty = vector_slot (vtyvec, i)) != NULL) && vty->monitor)
|
if (((vty = vector_slot (vtyvec, i)) != NULL) && vty->monitor)
|
||||||
/* N.B. We don't care about the return code, since process is
|
/* N.B. We don't care about the return code, since process is
|
||||||
most likely just about to die anyway. */
|
most likely just about to die anyway. */
|
||||||
if (writev(vty->fd, iov, 2) == -1)
|
if (writev(vty->wfd, iov, 2) == -1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failure to writev: %d\n", errno);
|
fprintf(stderr, "Failure to writev: %d\n", errno);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
@ -34,6 +34,9 @@ struct vty
|
|||||||
/* File descripter of this vty. */
|
/* File descripter of this vty. */
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
/* output FD, to support stdin/stdout combination */
|
||||||
|
int wfd;
|
||||||
|
|
||||||
/* Is this vty connect to file or not */
|
/* Is this vty connect to file or not */
|
||||||
enum {VTY_TERM, VTY_FILE, VTY_SHELL, VTY_SHELL_SERV} type;
|
enum {VTY_TERM, VTY_FILE, VTY_SHELL, VTY_SHELL_SERV} type;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user