diff options
-rw-r--r-- | lib/command_execute.c | 13 | ||||
-rw-r--r-- | lib/vty_command.c | 9 | ||||
-rw-r--r-- | lib/vty_command.h | 1 | ||||
-rw-r--r-- | lib/vty_io.c | 25 | ||||
-rw-r--r-- | lib/vty_io.h | 3 | ||||
-rw-r--r-- | lib/vty_io_file.c | 2 | ||||
-rw-r--r-- | lib/vty_io_term.c | 2 |
7 files changed, 35 insertions, 20 deletions
diff --git a/lib/command_execute.c b/lib/command_execute.c index 32698d94..cc457ba3 100644 --- a/lib/command_execute.c +++ b/lib/command_execute.c @@ -473,13 +473,13 @@ cmd_open_pipes(vty vty) cmd_parsed parsed = exec->parsed ; cmd_return_code_t ret ; vty_io vio ; - + bool sync_depth ; VTY_LOCK() ; vio = vty->vio ; ret = CMD_SUCCESS ; - uty_cmd_depth_mark(vio) ; /* about to push vin and/or vout */ + sync_depth = false ; /* assuming no in pipe */ /* Deal with any in pipe stuff */ if ((parsed->parts & cmd_part_in_pipe) != 0) @@ -499,6 +499,8 @@ cmd_open_pipes(vty vty) zabort("invalid in pipe state") ; qs_free(args) ; + + sync_depth = true ; } ; /* Deal with any out pipe stuff */ @@ -511,15 +513,18 @@ cmd_open_pipes(vty vty) if ((parsed->out_pipe & cmd_pipe_file) != 0) ret = uty_cmd_open_out_pipe_file(vio, exec->context, args, - parsed->out_pipe) ; + parsed->out_pipe) ; else if ((parsed->out_pipe & cmd_pipe_shell) != 0) ret = uty_cmd_open_out_pipe_shell(vio, exec->context, args, - parsed->out_pipe) ; + parsed->out_pipe) ; else if ((parsed->out_pipe & cmd_pipe_dev_null) != 0) ret = uty_cmd_open_out_dev_null(vio) ; else zabort("invalid out pipe state") ; + if (sync_depth && (ret == CMD_SUCCESS)) + uty_vout_sync_depth(vio) ; + qs_free(args) ; } ; diff --git a/lib/vty_command.c b/lib/vty_command.c index 94ba6833..a63f6f0c 100644 --- a/lib/vty_command.c +++ b/lib/vty_command.c @@ -1155,15 +1155,6 @@ vty_cmd_reflect_line(vty vty) } ; /*------------------------------------------------------------------------------ - * Set the vio->depth_mark -- about to push vin and/or vout - */ -extern void -uty_cmd_depth_mark(vty_io vio) -{ - vio->depth_mark = vio->vin_depth ; -} - -/*------------------------------------------------------------------------------ * Open the given file as an in pipe, if possible. * * Puts error messages to vty if fails. diff --git a/lib/vty_command.h b/lib/vty_command.h index 125b9a03..38c95604 100644 --- a/lib/vty_command.h +++ b/lib/vty_command.h @@ -46,7 +46,6 @@ extern cmd_return_code_t uty_cmd_out_push(vio_vf vf, bool final) ; extern void vty_cmd_set_full_lex(vty vty, bool full_lex) ; -extern void uty_cmd_depth_mark(vty_io vio) ; extern cmd_return_code_t uty_cmd_open_in_pipe_file(vty_io vio, cmd_context context, qstring name, cmd_pipe_type_t type) ; extern cmd_return_code_t uty_cmd_open_in_pipe_shell(vty_io vio, diff --git a/lib/vty_io.c b/lib/vty_io.c index 96df3850..619f8129 100644 --- a/lib/vty_io.c +++ b/lib/vty_io.c @@ -252,8 +252,6 @@ uty_new(vty_type_t type, node_type_t node) * vout_base = NULL -- empty output stack * vout_depth = 0 -- no stacked vout's, yet * - * depth_mark = 0 -- no stacked vin/vout, yet - * * err_hard = false -- no error at all, yet * ebuf = NULL -- no error at all, yet * @@ -365,12 +363,17 @@ uty_vin_new_context(vty_io vio, cmd_context context, qpath file_here) * * Initialises an output buffer and sets an end_mark. * - * The depth_mark is set to the current vio->depth_mark + 1. This is the + * The depth_mark is set to the current vio->vin_depth + 1. This is the * vin_depth below which the vout should be closed. Before a command line * is fetched (and hence after the previous command line has completed) the * vout->depth_mark is checked. If it is > the current vin_depth, then * the vout is closed before a command line can be fetched. * + * NB: where a vin and vout are opened together, so the vout should NOT + * be closed until after the vin, need to call uty_vout_sync_depth() + * *both* the vin and the vout are pushed, in order to set the correct + * depth_mark. + * * NB: is usually called from the cli thread, but may be called from the cmd * thread for vf which is blocking ! * @@ -417,12 +420,26 @@ uty_vout_push(vty_io vio, vio_vf vf, vio_out_type_t type, vf->obuf = vio_fifo_new(obuf_size) ; vio_fifo_set_end_mark(vf->obuf) ; - vf->depth_mark = vio->depth_mark + 1 ; + vf->depth_mark = vio->vin_depth + 1 ; vio->obuf = vf->obuf ; } ; /*------------------------------------------------------------------------------ + * Synchronise vout->depth_mark to current vin_depth. + * + * This *must* be called after a vin and vout have been opened together, and + * they are intended to be at the same depth. This applies when the base + * vin/vout are opened, and when an in pipe and an out pipe are present together + * on a command line. + */ +extern void +uty_vout_sync_depth(vty_io vio) +{ + vio->vout->depth_mark = vio->vin_depth ; +} ; + +/*------------------------------------------------------------------------------ * Set timeout value. * * This is only ever called when a command (eg exec-timeout) sets a new diff --git a/lib/vty_io.h b/lib/vty_io.h index 24790526..59ffb808 100644 --- a/lib/vty_io.h +++ b/lib/vty_io.h @@ -343,8 +343,6 @@ struct vty_io /* typedef appears above */ vio_vf vout_base ; uint vout_depth ; - uint depth_mark ; /* vin_depth before pipes opened */ - /* Error handling */ bool err_hard ; /* eg I/O error */ vio_fifo ebuf ; /* buffer for error message */ @@ -441,6 +439,7 @@ extern void uty_vout_push(vty_io vio, vio_vf vf, vio_out_type_t type, vio_vfd_action* write_action, vio_timer_action* write_timer_action, usize obuf_size) ; +extern void uty_vout_sync_depth(vty_io vio) ; extern cmd_return_code_t uty_vin_pop(vty_io vio, bool final, cmd_context context) ; extern cmd_return_code_t uty_vout_pop(vty_io vio, bool final) ; diff --git a/lib/vty_io_file.c b/lib/vty_io_file.c index 01a92a2d..4b1a8cfa 100644 --- a/lib/vty_io_file.c +++ b/lib/vty_io_file.c @@ -75,6 +75,8 @@ vty_config_read_open(int fd, const char* name, bool full_lex) uty_vin_push( vio, vf, VIN_CONFIG, NULL, NULL, 64 * 1024) ; uty_vout_push(vio, vf, VOUT_STDERR, NULL, NULL, 4 * 1024) ; + uty_vout_sync_depth(vio) ; /* vin & vout are at same level */ + /* Deal with the possibility that while reading the configuration file, may * use a pipe, and therefore may block waiting to collect a child process. * diff --git a/lib/vty_io_term.c b/lib/vty_io_term.c index aea04734..416968bf 100644 --- a/lib/vty_io_term.c +++ b/lib/vty_io_term.c @@ -164,6 +164,8 @@ uty_term_open(int sock_fd, union sockunion *su) uty_term_write_timeout, 4096) ; /* obuf is required */ + uty_vout_sync_depth(vio) ; /* vin & vout are at same level */ + vf->read_timeout = host.vty_timeout_val ; /* current EXEC timeout */ /* Set up the CLI object & initialise */ |