summaryrefslogtreecommitdiff
path: root/lib/vty.c
diff options
context:
space:
mode:
authorajs <ajs>2004-11-04 19:26:16 +0000
committerajs <ajs>2004-11-04 19:26:16 +0000
commit49ff6d9d7a9ef9419dd7aab58ac9f7806e3e1040 (patch)
treebb9e1d36b5bef56d2e47c69b6bab1ef54cf9696e /lib/vty.c
parent62d8e96a06e664c929a164bfb66b515d1c6877a8 (diff)
2004-11-04 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* vty.c: Vtysh connections to daemons should use buffering. (vty_out) Remove exception for vty_shell_serv, just use buffer_write. (vty_new) Increase output buffer size to 4096 rounded up to a multiple of pagesize. (vtysh_read) After command has been executed and all output buffered, call buffer_flush_available and schedule further writes if the buffers are not yet empty. (vtysh_write) New function to flush output to vtysh when the socket is writeable. (vty_event) Added new VTYSH_WRITE event for flushing buffers to vtysh clients. Also, should save read thread in vty->t_read so the thread can be cancelled in vty_close. * buffer.h: In struct buffer_data, remove unused "parent" field. Convert "unsigned char *data" to "unsigned char data[0]" to save a malloc. Declare new function buffer_flush_available that works with non-blocking sockets. * buffer.c: (buffer_data_new) Use a single malloc now that data is a variable-size array at end of structure. (buffer_data_free) Just a single free now that data is part of the structure. (buffer_write) Simplify the logic to make behavior more transparent. (buffer_flush) Decrease b->length as data is written out. (buffer_flush_vty_all) Decrease b->length as buffers are freed. (buffer_flush_vty) Decrease b->length as data is written out. (buffer_flush_available) New function to flush non-blocking sockets.
Diffstat (limited to 'lib/vty.c')
-rw-r--r--lib/vty.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/lib/vty.c b/lib/vty.c
index e37c99f5..e6bcb61a 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -45,10 +45,14 @@ enum event
VTY_TIMEOUT_RESET,
#ifdef VTYSH
VTYSH_SERV,
- VTYSH_READ
+ VTYSH_READ,
+ VTYSH_WRITE
#endif /* VTYSH */
};
+/* Minimum size of output buffers; to be rounded up to multiple of pagesize. */
+#define VTY_OBUF_SIZE 4096
+
static void vty_event (enum event, int, struct vty *);
/* Extern host structure from command.c */
@@ -127,10 +131,7 @@ vty_out (struct vty *vty, const char *format, ...)
p = buf;
/* Pointer p must point out buffer. */
- if (vty_shell_serv (vty))
- write (vty->fd, (u_char *) p, len);
- else
- buffer_write (vty->obuf, (u_char *) p, len);
+ buffer_write (vty->obuf, (u_char *) p, len);
/* If p is not different with buf, it is allocated buffer. */
if (p != buf)
@@ -264,8 +265,9 @@ struct vty *
vty_new ()
{
struct vty *new = XCALLOC (MTYPE_VTY, sizeof (struct vty));
+ int pgsz = getpagesize();
- new->obuf = (struct buffer *) buffer_new (100);
+ new->obuf = (struct buffer *) buffer_new ((((VTY_OBUF_SIZE-1)/pgsz)+1)*pgsz);
new->buf = XCALLOC (MTYPE_VTY, VTY_BUFSIZ);
new->max = VTY_BUFSIZ;
new->sb_buffer = NULL;
@@ -2014,12 +2016,25 @@ vtysh_read (struct thread *thread)
#endif /* VTYSH_DEBUG */
header[3] = ret;
- write (vty->fd, header, 4);
+ buffer_write(vty->obuf, header, 4);
+ if (!vty->t_write && buffer_flush_available(vty->obuf, vty->fd))
+ vty_event (VTYSH_WRITE, vty->fd, vty);
vty_event (VTYSH_READ, sock, vty);
return 0;
}
+
+static int
+vtysh_write (struct thread *thread)
+{
+ struct vty *vty = THREAD_ARG (thread);
+
+ vty->t_write = NULL;
+ if (buffer_flush_available(vty->obuf, vty->fd))
+ vty_event (VTYSH_WRITE, vty->fd, vty);
+}
+
#endif /* VTYSH */
/* Determine address family to bind. */
@@ -2364,7 +2379,10 @@ vty_event (enum event event, int sock, struct vty *vty)
thread_add_read (master, vtysh_accept, vty, sock);
break;
case VTYSH_READ:
- thread_add_read (master, vtysh_read, vty, sock);
+ vty->t_read = thread_add_read (master, vtysh_read, vty, sock);
+ break;
+ case VTYSH_WRITE:
+ vty->t_write = thread_add_write (master, vtysh_write, vty, sock);
break;
#endif /* VTYSH */
case VTY_READ: