From 5cae7eea451f2b7d65b5892e2c1dafc70f8b836e Mon Sep 17 00:00:00 2001 From: Chris Hall Date: Sun, 13 Feb 2011 23:11:45 +0000 Subject: Second tranche of updates for pipework branch. modified: bgpd/bgp_connection.c modified: bgpd/bgp_debug.c modified: bgpd/bgp_engine.h modified: bgpd/bgp_main.c modified: bgpd/bgp_packet.c modified: bgpd/bgp_peer.c modified: bgpd/bgp_route.c modified: bgpd/bgp_routemap.c modified: bgpd/bgp_session.c modified: bgpd/bgp_vty.c modified: bgpd/bgpd.c modified: bgpd/bgpd.h modified: configure.ac modified: isisd/dict.h modified: isisd/isis_misc.c modified: isisd/isis_routemap.c modified: isisd/isis_spf.c modified: lib/Makefile.am modified: lib/command.c modified: lib/command.h modified: lib/command_execute.h modified: lib/command_parse.c modified: lib/command_parse.h modified: lib/command_queue.c modified: lib/command_queue.h modified: lib/elstring.h modified: lib/heap.c modified: lib/if.c modified: lib/if.h modified: lib/keychain.c modified: lib/keystroke.c modified: lib/keystroke.h modified: lib/list_util.c modified: lib/list_util.h modified: lib/log.c modified: lib/log.h modified: lib/memory.c modified: lib/memory.h modified: lib/memtypes.c modified: lib/misc.h modified: lib/mqueue.c modified: lib/mqueue.h deleted: lib/node_type.h modified: lib/pthread_safe.c modified: lib/qfstring.c modified: lib/qiovec.c modified: lib/qiovec.h modified: lib/qpath.c modified: lib/qpnexus.c modified: lib/qpnexus.h modified: lib/qpselect.c modified: lib/qpthreads.h modified: lib/qstring.c modified: lib/qstring.h modified: lib/qtime.c modified: lib/qtime.h modified: lib/qtimers.c modified: lib/qtimers.h modified: lib/routemap.c modified: lib/symtab.h modified: lib/thread.h deleted: lib/uty.h modified: lib/vector.c modified: lib/vector.h modified: lib/version.h.in modified: lib/vio_fifo.c modified: lib/vio_fifo.h modified: lib/vio_lines.c modified: lib/vio_lines.h modified: lib/vty.c modified: lib/vty.h modified: lib/vty_cli.c modified: lib/vty_cli.h modified: lib/vty_io.c modified: lib/vty_io.h modified: lib/vty_io_basic.c modified: lib/vty_io_basic.h modified: lib/vty_io_file.c modified: lib/vty_io_file.h modified: lib/vty_io_shell.c modified: lib/vty_io_term.c modified: lib/vty_io_term.h modified: lib/vty_local.h modified: lib/vty_pipe.c modified: lib/workqueue.h modified: lib/zebra.h modified: ospf6d/ospf6_lsa.c modified: ripngd/ripngd.c modified: tests/test-list_util.c modified: tests/test-vector.c modified: vtysh/vtysh.c modified: vtysh/vtysh_config.c --- lib/vty_io_basic.c | 387 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 218 insertions(+), 169 deletions(-) (limited to 'lib/vty_io_basic.c') diff --git a/lib/vty_io_basic.c b/lib/vty_io_basic.c index 3bead51f..85ea2587 100644 --- a/lib/vty_io_basic.c +++ b/lib/vty_io_basic.c @@ -21,9 +21,67 @@ * 02111-1307, USA. */ -#include "zebra.h" - #include "vty_io_basic.h" +#include "vty_local.h" + +#include "memory.h" + +#include +#include + +/*============================================================================== + * Base level open operations -- files and pipes + * + */ + +/*============================================================================== + * Try to open the given file for the given type of I/O. + * + * vfd_io_write => create if does not exist (mode 0600) + * + * vfd_io_append => set O_APPEND + * otherwise => truncate file if it does exist + * + * vfd_io_read => fail if does not exist + * + * vfd_io_read_write => create if does not exist (mode 0600) + * + * vfd_io_append => set O_APPEND + * otherwise => leave file as is + * + * vfd_io_blocking => do not open O_NONBLOCK + * + * (if none of the above, treat as vfd_io_read) + * + * Returns: if >= 0 -- the fd of the open file + * < 0 -- failed to open file -- see errno + */ +extern int +uty_vfd_file_open(const char* name, vfd_io_type_t io_type) +{ + int oflag ; + + oflag = 0 ; + if ((io_type & vfd_io_read_write) == vfd_io_read_write) + oflag = O_RDWR | O_CREAT ; + else if ((io_type & vfd_io_write) != 0) + oflag = O_WRONLY | O_CREAT ; + else + oflag = O_RDONLY ; + + if ((io_type & vfd_io_write) != 0) + { + if ((io_type & vfd_io_append) != 0) + oflag |= O_APPEND ; + else if ((io_type & vfd_io_read) == 0) + oflag |= O_TRUNC ; + } ; + + if ((io_type & vfd_io_blocking) == 0) + oflag |= O_NONBLOCK ; + + return open(name, oflag, S_IRUSR | S_IWUSR) ; +} ; /*============================================================================== * Base level I/O and Timer handling.... @@ -34,25 +92,23 @@ struct vio_io_set_args /* to CLI thread */ { - bool active ; /* set when queued, cleared when dequeued */ - bool die ; /* set when is queued and vio_fd is closed */ - bool close ; /* close and free the vio_fd and mqb */ + bool active ; /* set when queued, cleared when dequeued */ + bool close ; /* close and free the vio_vfd and mqb */ bool readable ; /* set when read state to be changed */ - on_off_t read_on ; /* what to change read to */ + on_off_b read_on ; /* what to change read to */ vty_timer_time read_timeout ; /* what to set the timeout to, if any */ bool writable ; /* set when write state to be changed */ - on_off_t write_on ; /* what to change write to */ + on_off_b write_on ; /* what to change write to */ vty_timer_time write_timeout ; /* what to set the timeout to, if any */ } ; MQB_ARGS_SIZE_OK(vio_io_set_args) ; -static void vio_fd_mqb_dispatch(vio_fd vfd) ; -static void vio_fd_mqb_free(vio_fd vfd) ; -static struct vio_io_set_args* vio_fd_mqb_args(vio_fd vfd) ; +static void vio_vfd_mqb_dispatch(vio_vfd vfd) ; +static struct vio_io_set_args* vio_vfd_mqb_args(vio_vfd vfd) ; /*============================================================================== * File Descriptor handling @@ -69,22 +125,22 @@ static struct vio_io_set_args* vio_fd_mqb_args(vio_fd vfd) ; * see above. */ -static void vio_fd_qps_read_action(qps_file qf, void* file_info) ; -static void vio_fd_qps_write_action(qps_file qf, void* file_info) ; -static int vio_fd_thread_read_action(struct thread *thread) ; -static int vio_fd_thread_write_action(struct thread *thread) ; +static void vio_vfd_qps_read_action(qps_file qf, void* file_info) ; +static void vio_vfd_qps_write_action(qps_file qf, void* file_info) ; +static int vio_vfd_thread_read_action(struct thread *thread) ; +static int vio_vfd_thread_write_action(struct thread *thread) ; static void vio_timer_squelch(vio_timer_t* timer) ; Inline void -vio_fd_do_read_action(vio_fd vfd) +vio_vfd_do_read_action(vio_vfd vfd) { if (vfd->active) vfd->read_action(vfd, vfd->action_info) ; } Inline void -vio_fd_do_write_action(vio_fd vfd) +vio_vfd_do_write_action(vio_vfd vfd) { if (vfd->active) vfd->write_action(vfd, vfd->action_info) ; @@ -93,12 +149,12 @@ vio_fd_do_write_action(vio_fd vfd) /*------------------------------------------------------------------------------ * Create a new vfd structure. */ -extern vio_fd -vio_fd_new(int fd, vfd_type_t type, vfd_io_type_t io_type, void* action_info) +extern vio_vfd +vio_vfd_new(int fd, vfd_type_t type, vfd_io_type_t io_type, void* action_info) { - vio_fd vfd ; + vio_vfd vfd ; - vfd = XCALLOC(MTYPE_VTY, sizeof(struct vio_fd)) ; + vfd = XCALLOC(MTYPE_VTY, sizeof(struct vio_vfd)) ; /* Has set: * @@ -114,12 +170,12 @@ vio_fd_new(int fd, vfd_type_t type, vfd_io_type_t io_type, void* action_info) * mqb -- NULL */ - vio_fd_set_fd(vfd, fd, type, io_type) ; + vio_vfd_set_fd(vfd, fd, type, io_type) ; vio_timer_init(&vfd->read_timer, NULL, NULL) ; vio_timer_init(&vfd->write_timer, NULL, NULL) ; - vio_fd_set_action_info(vfd, action_info) ; + vio_vfd_set_action_info(vfd, action_info) ; return vfd ; } ; @@ -127,13 +183,13 @@ vio_fd_new(int fd, vfd_type_t type, vfd_io_type_t io_type, void* action_info) /*------------------------------------------------------------------------------ * If vfd was not fully set up when created, set it up now. * - * To close an active vfd, use vio_fd_close() ! + * To close an active vfd, use vio_vfd_close() ! * * NB: for use when vfd has been created, but the fd was not known at that * time -- ie the vfd is NOT active. */ extern void -vio_fd_set_fd(vio_fd vfd, int fd, vfd_type_t type, vfd_io_type_t io_type) +vio_vfd_set_fd(vio_vfd vfd, int fd, vfd_type_t type, vfd_io_type_t io_type) { assert(!vfd->active) ; @@ -144,74 +200,76 @@ vio_fd_set_fd(vio_fd vfd, int fd, vfd_type_t type, vfd_io_type_t io_type) } ; /*------------------------------------------------------------------------------ - * Set the read action field for the given vio_fd. + * Set the read action field for the given vio_vfd. */ extern void -vio_fd_set_read_action(vio_fd vfd, vio_fd_action* action) +vio_vfd_set_read_action(vio_vfd vfd, vio_vfd_action* action) { vfd->read_action = action ; } ; /*------------------------------------------------------------------------------ - * Set the write action field for the given vio_fd. + * Set the write action field for the given vio_vfd. */ extern void -vio_fd_set_write_action(vio_fd vfd, vio_fd_action* action) +vio_vfd_set_write_action(vio_vfd vfd, vio_vfd_action* action) { vfd->write_action = action ; } ; /*------------------------------------------------------------------------------ - * Set the read action field for the given vio_fd. + * Set the read action field for the given vio_vfd. */ extern void -vio_fd_set_read_timeout_action(vio_fd vfd, vio_timer_action* action) +vio_vfd_set_read_timeout_action(vio_vfd vfd, vio_timer_action* action) { vio_timer_set_action(&vfd->read_timer, action) ; } ; /*------------------------------------------------------------------------------ - * Set the write action field for the given vio_fd. + * Set the write action field for the given vio_vfd. */ extern void -vio_fd_set_write_timeout_action(vio_fd vfd, vio_timer_action* action) +vio_vfd_set_write_timeout_action(vio_vfd vfd, vio_timer_action* action) { vio_timer_set_action(&vfd->write_timer, action) ; } ; /*------------------------------------------------------------------------------ - * Set the action_info field for the given vio_fd read/write action. + * Set the action_info field for the given vio_vfd read/write action. */ extern void -vio_fd_set_action_info(vio_fd vfd, void* action_info) +vio_vfd_set_action_info(vio_vfd vfd, void* action_info) { vfd->action_info = action_info ; vio_timer_set_info(&vfd->read_timer, action_info) ; vio_timer_set_info(&vfd->write_timer, action_info) ; } ; +#if 0 /*------------------------------------------------------------------------------ - * If there is a read action set for the give vio_fd (if any), then kick it. + * If there is a read action set for the give vio_vfd (if any), then kick it. */ extern void -vio_fd_do_read_action(vio_fd vfd) +vio_vfd_kick_read_action(vio_vfd vfd) { if ((vfd != NULL) && (vfd->read_action != NULL)) - vio_fd_do_read_action(vfd) ; + vio_vfd_do_read_action(vfd) ; } ; /*------------------------------------------------------------------------------ - * If there is a write action set for the give vio_fd (if any), then kick it. + * If there is a write action set for the give vio_vfd (if any), then kick it. */ extern void -vio_fd_do_write_action(vio_fd vfd) +vio_vfd_kick_write_action(vio_vfd vfd) { if ((vfd != NULL) && (vfd->write_action != NULL)) - vio_fd_do_read_action(vfd) ; + vio_vfd_do_read_action(vfd) ; } ; +#endif /*------------------------------------------------------------------------------ - * Half close the given vfd (if any). + * Close the read side of the given vfd (if any). * * If the vfd is a socket, then does a shutdown of the read side. * @@ -221,8 +279,8 @@ vio_fd_do_write_action(vio_fd vfd) * * Returns original vfd, or NULL if it has been closed. */ -extern vio_fd -vio_fd_half_close(vio_fd vfd) +extern vio_vfd +vio_vfd_read_close(vio_vfd vfd) { VTY_ASSERT_LOCKED() ; @@ -239,14 +297,14 @@ vio_fd_half_close(vio_fd vfd) { /* read & write, so really half-close if can */ if (vfd->type == vfd_socket) - shutdown(vfd->fd, SHUT_RD) ; - vio_fd_set_read(vfd, off, 0) ; + shutdown(vfd->fd, SHUT_RD) ; /* ignore errors TODO */ + vio_vfd_set_read(vfd, off, 0) ; vfd->io_type ^= vfd_io_read ; /* now write only ! */ } else { /* read only, so fully close */ - vfd = vio_fd_close(vfd) ; + vfd = vio_vfd_close(vfd) ; } ; } ; } @@ -259,32 +317,31 @@ vio_fd_half_close(vio_fd vfd) /*------------------------------------------------------------------------------ * If there is an fd, close it. * - * Stops any read/write waiting and releases all memory. - * - * NB: this can done from any thread, but if not done from the CLI thread, - * and there is a qf, a message must be sent to the CLI thread to actually - * implement: which passes the vio_fd to the CLI thread for later - * close and destruction. - * - * The actual close has to be delayed, so that cannot open another fd - * and bang into a still active qps_file ! - * - * The message looks after freeing the vio_fd, the qps_file and the mqb. + * Stops any read/write waiting and releases all memory, including the vfd + * itself if required.. */ static void -vio_fd_do_close(vio_fd vfd) +vio_vfd_do_close(vio_vfd vfd, free_keep_b free) { + if (vfd == NULL) + return ; + VTY_ASSERT_LOCKED() ; VTY_ASSERT_CLI_THREAD() ; - if (vty_cli_nexus) + if (vty_nexus) { if (vfd->f.qf != NULL) { assert(vfd->fd == qps_file_fd(vfd->f.qf)) ; vfd->f.qf = qps_file_free(vfd->f.qf) ; } ; - vio_fd_mqb_free(vfd) ; + + if (vfd->mqb != NULL) + { + mqb_free(vfd->mqb) ; + vfd->mqb = NULL ; + } ; } else { @@ -306,12 +363,13 @@ vio_fd_do_close(vio_fd vfd) } ; if (vfd->fd >= 0) - close(vfd->fd) ; + close(vfd->fd) ; /* ignores errors TODO */ vio_timer_reset(&vfd->read_timer) ; vio_timer_reset(&vfd->write_timer) ; - XFREE(MTYPE_VTY, vfd) ; + if (free == free_it) + XFREE(MTYPE_VTY, vfd) ; } ; /*------------------------------------------------------------------------------ @@ -322,16 +380,16 @@ vio_fd_do_close(vio_fd vfd) * * NB: this can done from any thread, but if not done from the CLI thread, * and there is a qf, a message must be sent to the CLI thread to actually - * implement: which passes the vio_fd to the CLI thread for later + * implement: which passes the vio_vfd to the CLI thread for later * close and destruction. * * The actual close has to be delayed, so that cannot open another fd * and bang into a still active qps_file ! * - * The message looks after freeing the vio_fd, the qps_file and the mqb. + * The message looks after freeing the vio_vfd, the qps_file and the mqb. */ -extern vio_fd -vio_fd_close(vio_fd vfd) +extern vio_vfd +vio_vfd_close(vio_vfd vfd) { VTY_ASSERT_LOCKED() ; @@ -340,9 +398,9 @@ vio_fd_close(vio_fd vfd) if (vfd->fd < 0) { - /* closing an inactive vio_fd -- make sure all is quiet */ + /* closing an inactive vio_vfd -- make sure all is quiet */ assert(!vfd->active) ; - if (vty_cli_nexus) + if (vty_nexus) { assert(vfd->f.qf == NULL) ; } @@ -355,19 +413,18 @@ vio_fd_close(vio_fd vfd) } else { - /* closing an active vio_fd */ + /* closing an active vio_vfd */ if (vty_is_cli_thread()) { /* In cli thread, so close directly */ - vio_fd_do_close(vfd) ; + vio_vfd_do_close(vfd, free_it) ; } else { /* Rats... have to send message to cli thread to close */ - struct vio_io_set_args* args = vio_fd_mqb_args(vfd) ; + struct vio_io_set_args* args = vio_vfd_mqb_args(vfd) ; args->close = true ; - args->die = true ; /* in case something goes ready before the close message * is processed, squelch. @@ -381,7 +438,7 @@ vio_fd_close(vio_fd vfd) vio_timer_squelch(&vfd->write_timer) ; assert(vfd == mqb_get_arg0(vfd->mqb)) ; - vio_fd_mqb_dispatch(vfd) ; + vio_vfd_mqb_dispatch(vfd) ; } ; } ; @@ -389,16 +446,16 @@ vio_fd_close(vio_fd vfd) } ; /*------------------------------------------------------------------------------ - * Set or unset read ready state on given vio_fd (if any) if it is active. + * Set or unset read ready state on given vio_vfd (if any) if it is active. * - * If setting read_on, starts any read timeout timer. + * If setting read_on, starts any read timeout timer (or stops it if 0). * If setting read off, stops any read timeout timer. * * NB: this can done from any thread, but if not done from the CLI thread, * a message must be sent to the CLI thread to actually implement. */ -extern on_off_t -vio_fd_set_read(vio_fd vfd, on_off_t on, vty_timer_time timeout) +extern on_off_b +vio_vfd_set_read(vio_vfd vfd, on_off_b on, vty_timer_time timeout) { struct vio_io_set_args* args ; @@ -422,7 +479,7 @@ vio_fd_set_read(vio_fd vfd, on_off_t on, vty_timer_time timeout) { assert(vfd->read_action != NULL) ; - if (vty_cli_nexus) + if (vty_nexus) { if (vfd->f.qf == NULL) { @@ -431,20 +488,20 @@ vio_fd_set_read(vio_fd vfd, on_off_t on, vty_timer_time timeout) vfd->fd, vfd) ; } ; qps_enable_mode(vfd->f.qf, qps_read_mnum, - vio_fd_qps_read_action) ; + vio_vfd_qps_read_action) ; } else { if (vfd->f.thread.read == NULL) vfd->f.thread.read = thread_add_read(vty_master, - vio_fd_thread_read_action, vfd, vfd->fd) ; + vio_vfd_thread_read_action, vfd, vfd->fd) ; } ; vio_timer_set(&vfd->read_timer, timeout) ; } else { - if (vty_cli_nexus) + if (vty_nexus) { if (vfd->f.qf != NULL) qps_disable_modes(vfd->f.qf, qps_read_mbit) ; @@ -462,19 +519,19 @@ vio_fd_set_read(vio_fd vfd, on_off_t on, vty_timer_time timeout) { /* In other threads, must send message to cli thread */ - args = vio_fd_mqb_args(vfd) ; + args = vio_vfd_mqb_args(vfd) ; args->readable = true ; args->read_on = on ; args->read_timeout = timeout ; vio_timer_squelch(&vfd->read_timer) ; - vio_fd_mqb_dispatch(vfd) ; + vio_vfd_mqb_dispatch(vfd) ; } ; return on ; } ; /*------------------------------------------------------------------------------ - * Set or unset write ready state on given vio_fd (if any) if it is active. + * Set or unset write ready state on given vio_vfd (if any) if it is active. * * If setting write_on, starts any write timeout timer. * If setting write off, stops any write timeout timer. @@ -482,8 +539,8 @@ vio_fd_set_read(vio_fd vfd, on_off_t on, vty_timer_time timeout) * NB: this can done from any thread, but if not done from the CLI thread, * a message must be sent to the CLI thread to actually implement. */ -extern on_off_t -vio_fd_set_write(vio_fd vfd, on_off_t on, vty_timer_time timeout) +extern on_off_b +vio_vfd_set_write(vio_vfd vfd, on_off_b on, vty_timer_time timeout) { struct vio_io_set_args* args ; @@ -507,7 +564,7 @@ vio_fd_set_write(vio_fd vfd, on_off_t on, vty_timer_time timeout) { assert(vfd->write_action != NULL) ; - if (vty_cli_nexus) + if (vty_nexus) { if (vfd->f.qf == NULL) { @@ -516,20 +573,20 @@ vio_fd_set_write(vio_fd vfd, on_off_t on, vty_timer_time timeout) vfd->fd, vfd) ; } ; qps_enable_mode(vfd->f.qf, qps_write_mnum, - vio_fd_qps_write_action) ; + vio_vfd_qps_write_action) ; } else { if (vfd->f.thread.write == NULL) vfd->f.thread.write = thread_add_write(vty_master, - vio_fd_thread_write_action, vfd, vfd->fd) ; + vio_vfd_thread_write_action, vfd, vfd->fd) ; } ; vio_timer_set(&vfd->write_timer, timeout) ; } else { - if (vty_cli_nexus) + if (vty_nexus) { if (vfd->f.qf != NULL) qps_disable_modes(vfd->f.qf, qps_write_mbit) ; @@ -547,12 +604,12 @@ vio_fd_set_write(vio_fd vfd, on_off_t on, vty_timer_time timeout) { /* In other threads, must send message to cli thread */ - args = vio_fd_mqb_args(vfd) ; + args = vio_vfd_mqb_args(vfd) ; args->writable = true ; args->write_on = on ; args->write_timeout = timeout ; vio_timer_squelch(&vfd->write_timer) ; - vio_fd_mqb_dispatch(vfd) ; + vio_vfd_mqb_dispatch(vfd) ; } ; return on ; @@ -567,19 +624,21 @@ vio_fd_set_write(vio_fd vfd, on_off_t on, vty_timer_time timeout) * message is yet to be procesed. */ static void -vio_fd_qps_read_action(qps_file qf, void* file_info) +vio_vfd_qps_read_action(qps_file qf, void* file_info) { - vio_fd vfd = file_info ; + vio_vfd vfd ; - VTY_LOCK() ; VTY_ASSERT_CLI_THREAD() ; + VTY_LOCK() ; + + vfd = file_info ; assert((vfd->fd == qf->fd) && (vfd->f.qf == qf)) ; qps_disable_modes(vfd->f.qf, qps_read_mbit) ; vio_timer_unset(&vfd->read_timer) ; - vio_fd_do_read_action(vfd) ; + vio_vfd_do_read_action(vfd) ; VTY_UNLOCK() ; } ; @@ -593,19 +652,21 @@ vio_fd_qps_read_action(qps_file qf, void* file_info) * message is yet to be procesed. */ static int -vio_fd_thread_read_action(struct thread *thread) +vio_vfd_thread_read_action(struct thread *thread) { - vio_fd vfd = THREAD_ARG (thread); + vio_vfd vfd ; - VTY_LOCK() ; VTY_ASSERT_CLI_THREAD() ; + VTY_LOCK() ; + + vfd = THREAD_ARG(thread); assert(vfd->fd == THREAD_FD(thread)) ; vfd->f.thread.read = NULL ; /* implicitly */ vio_timer_unset(&vfd->read_timer) ; - vio_fd_do_read_action(vfd) ; + vio_vfd_do_read_action(vfd) ; VTY_UNLOCK() ; return 0 ; @@ -620,19 +681,19 @@ vio_fd_thread_read_action(struct thread *thread) * message is yet to be procesed. */ static void -vio_fd_qps_write_action(qps_file qf, void* file_info) +vio_vfd_qps_write_action(qps_file qf, void* file_info) { - vio_fd vfd = file_info ; + vio_vfd vfd = file_info ; - VTY_LOCK() ; VTY_ASSERT_CLI_THREAD() ; + VTY_LOCK() ; assert((vfd->fd == qf->fd) && (vfd->f.qf == qf)) ; qps_disable_modes(vfd->f.qf, qps_write_mbit) ; vio_timer_unset(&vfd->write_timer) ; - vio_fd_do_write_action(vfd) ; + vio_vfd_do_write_action(vfd) ; VTY_UNLOCK() ; } ; @@ -646,19 +707,19 @@ vio_fd_qps_write_action(qps_file qf, void* file_info) * message is yet to be procesed. */ static int -vio_fd_thread_write_action(struct thread *thread) +vio_vfd_thread_write_action(struct thread *thread) { - vio_fd vfd = THREAD_ARG (thread); + vio_vfd vfd = THREAD_ARG (thread); - VTY_LOCK() ; VTY_ASSERT_CLI_THREAD() ; + VTY_LOCK() ; assert(vfd->fd == THREAD_FD(thread)) ; vio_timer_unset(&vfd->write_timer) ; vfd->f.thread.write = NULL ; /* implicitly */ - vio_fd_do_write_action(vfd) ; + vio_vfd_do_write_action(vfd) ; VTY_UNLOCK() ; return 0 ; @@ -675,57 +736,31 @@ vio_fd_thread_write_action(struct thread *thread) * further dispatch is required. When it has been dequeued and processed, * it is marked inactive. * - * If the vfd is closed while the message is active, it is marked to die, + * If the vfd is closed while the message is active, it is marked to close, * which it will do when it is dequeued and actioned. */ -static void vio_fd_set_action(mqueue_block mqb, mqb_flag_t flag) ; +static void vio_vfd_set_action(mqueue_block mqb, mqb_flag_t flag) ; /*------------------------------------------------------------------------------ * Get mqb for the given vfd -- make one if required. */ static struct vio_io_set_args* -vio_fd_mqb_args(vio_fd vfd) +vio_vfd_mqb_args(vio_vfd vfd) { VTY_ASSERT_LOCKED() ; if (vfd->mqb == NULL) - vfd->mqb = mqb_init_new(NULL, vio_fd_set_action, vfd) ; + vfd->mqb = mqb_init_new(NULL, vio_vfd_set_action, vfd) ; return mqb_get_args(vfd->mqb) ; } ; -/*------------------------------------------------------------------------------ - * Free mqb for the given vfd -- if any. - */ -static void -vio_fd_mqb_free(vio_fd vfd) -{ - VTY_ASSERT_LOCKED() ; - - if (vfd->mqb != NULL) - { - struct vio_io_set_args* args = mqb_get_args(vfd->mqb) ; - - if (args->active) - { - args->die = true ; - mqb_set_arg0(vfd->mqb, NULL) ; - } - else - { - mqb_free(vfd->mqb) ; - } ; - - vfd->mqb = NULL ; - } ; -} ; - /*------------------------------------------------------------------------------ * Dispatch mqb, if not already active */ static void -vio_fd_mqb_dispatch(vio_fd vfd) +vio_vfd_mqb_dispatch(vio_vfd vfd) { struct vio_io_set_args* args = mqb_get_args(vfd->mqb) ; @@ -741,33 +776,43 @@ vio_fd_mqb_dispatch(vio_fd vfd) /*------------------------------------------------------------------------------ * Action routine for the read/write on/off setting message. * - * If the mqb is marked to die, then it and any qps_file it points to have been - * cut loose, and now is the time to close the fd and release the qps_file, - * along with releasing the mqb. + * If the mqb is marked to close, then it and any qps_file it points to have + * been cut loose, and now is the time to close the fd and release the + * qps_file, along with releasing the mqb. + * + * If the mqb is being revoked */ static void -vio_fd_set_action(mqueue_block mqb, mqb_flag_t flag) +vio_vfd_set_action(mqueue_block mqb, mqb_flag_t flag) { - struct vio_io_set_args* args = mqb_get_args(mqb) ; - vio_fd vfd = mqb_get_arg0(mqb) ; + struct vio_io_set_args* args ; + vio_vfd vfd ; - VTY_LOCK() ; VTY_ASSERT_CLI_THREAD() ; + VTY_LOCK() ; + + args = mqb_get_args(mqb) ; + vfd = mqb_get_arg0(mqb) ; args->active = false ; - if ((flag != mqb_destroy) && (!args->die)) + if ((flag != mqb_destroy) && (!args->close)) { if (args->readable) - vio_fd_set_read(vfd, args->read_on, args->read_timeout) ; + vio_vfd_set_read(vfd, args->read_on, args->read_timeout) ; if (args->writable) - vio_fd_set_write(vfd, args->write_on, args->write_timeout) ; + vio_vfd_set_write(vfd, args->write_on, args->write_timeout) ; } else { - if (args->close) - vio_fd_do_close(vfd) ; - mqb_free(mqb) ; + /* Revoke and/or close. + * + * If close can free the vfd. + * + * If just revoke (should not happen), then cannot free the vfd, because + * somewhere there can be a dangling reference. + */ + vio_vfd_do_close(vfd, args->close) ; /* frees the mqb */ } ; VTY_UNLOCK() ; @@ -779,7 +824,7 @@ vio_fd_set_action(mqueue_block mqb, mqb_flag_t flag) * */ -static void vio_accept(vio_fd vfd, void* info) ; +static void vio_accept(vio_vfd vfd, void* info) ; /*------------------------------------------------------------------------------ * Create a new listener object for the newly opened listener socket. @@ -790,7 +835,7 @@ static void vio_accept(vio_fd vfd, void* info) ; * Returns address of newly created listener structure. */ extern vio_listener -vio_listener_new(int fd, vio_fd_accept* accept_action) +vio_listener_new(int fd, vio_vfd_accept* accept_action) { vio_listener listener ; @@ -800,12 +845,12 @@ vio_listener_new(int fd, vio_fd_accept* accept_action) listener = XCALLOC(MTYPE_VTY, sizeof(struct vio_listener)) ; /* sets the next pointer to NULL */ - listener->vfd = vio_fd_new(fd, vfd_listener, vfd_io_read, listener) ; + listener->vfd = vio_vfd_new(fd, vfd_listener, vfd_io_read, listener) ; listener->accept_action = accept_action ; - vio_fd_set_read_action(listener->vfd, vio_accept) ; - vio_fd_set_read(listener->vfd, on, 0) ; + vio_vfd_set_read_action(listener->vfd, vio_accept) ; + vio_vfd_set_read(listener->vfd, on, 0) ; return listener ; } ; @@ -822,7 +867,7 @@ vio_listener_close(vio_listener listener) VTY_ASSERT_LOCKED() ; VTY_ASSERT_CLI_THREAD() ; - vio_fd_close(listener->vfd) ; + vio_vfd_close(listener->vfd) ; XFREE(MTYPE_VTY, listener) ; } ; @@ -832,7 +877,7 @@ vio_listener_close(vio_listener listener) * info points at the listener object. */ static void -vio_accept(vio_fd vfd, void* info) +vio_accept(vio_vfd vfd, void* info) { vio_listener listener ; @@ -842,6 +887,8 @@ vio_accept(vio_fd vfd, void* info) listener = info ; assert(vfd == listener->vfd) ; + vio_vfd_set_read(listener->vfd, on, 0) ; + listener->accept_action(vfd->fd) ; } ; @@ -902,7 +949,6 @@ static void vio_timer_squelch(vio_timer_t* timer) { VTY_ASSERT_LOCKED() ; - VTY_ASSERT_CLI_THREAD() ; timer->squelch = true ; } ; @@ -920,7 +966,7 @@ vio_timer_reset(vio_timer_t* timer) if (timer->t.anon != NULL) { - if (vty_cli_nexus) + if (vty_nexus) qtimer_free(timer->t.qtr) ; else thread_cancel(timer->t.thread) ; @@ -953,7 +999,7 @@ vio_timer_set(vio_timer_t* timer, vty_timer_time time) assert(timer->action != NULL) ; - if (vty_cli_nexus) + if (vty_nexus) { if (timer->t.qtr == NULL) /* allocate qtr if required */ timer->t.qtr = qtimer_init_new(NULL, vty_cli_nexus->pile, @@ -983,7 +1029,7 @@ vio_timer_unset(vio_timer_t* timer) if (timer->active) { - if (vty_cli_nexus) + if (vty_nexus) { assert(timer->t.qtr != NULL) ; qtimer_unset(timer->t.qtr) ; @@ -1007,13 +1053,15 @@ vio_timer_unset(vio_timer_t* timer) static void vio_timer_qtr_action(qtimer qtr, void* timer_info, qtime_t when) { - vio_timer_t* timer = timer_info ; + vio_timer_t* timer ; vty_timer_time time ; - VTY_LOCK() ; VTY_ASSERT_CLI_THREAD() ; + VTY_LOCK() ; + + timer = timer_info ; - if (!timer->squelch) /* do nothing if squelched */ + if ((timer->action != NULL) && (!timer->squelch)) { time = timer->action(timer, timer->action_info) ; if (time != 0) @@ -1036,15 +1084,16 @@ vio_timer_qtr_action(qtimer qtr, void* timer_info, qtime_t when) static int vio_timer_thread_action(struct thread *thread) { - vio_timer_t* timer = THREAD_ARG (thread); + vio_timer_t* timer ; vty_timer_time time ; - VTY_LOCK() ; VTY_ASSERT_CLI_THREAD() ; + VTY_LOCK() ; + timer = THREAD_ARG(thread) ; timer->t.thread = NULL ; /* implicitly */ - if (!timer->squelch) /* do nothing if squelched */ + if ((timer->action != NULL) && (!timer->squelch)) { time = timer->action(timer, timer->action_info) ; if (time != 0) -- cgit v1.2.3