summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/command_execute.c13
-rw-r--r--lib/vty_command.c9
-rw-r--r--lib/vty_command.h1
-rw-r--r--lib/vty_io.c25
-rw-r--r--lib/vty_io.h3
-rw-r--r--lib/vty_io_file.c2
-rw-r--r--lib/vty_io_term.c2
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 */