#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
+#include <netinet/tcp.h>
/** ANSI escape code. */
#define ESC "\x1b"
* @param str The buffer in which to search for the value.
* @param len The depth into the buffer to search.
*
- * @return The index of the first occurence of \c chr. If \c chr is not
+ * @return The index of the first occurrence of \c chr. If \c chr is not
* found then \c len instead.
*/
always_inline word
*
* If instead @c line is @c NULL then @c len_or_index is taken to mean the
* index of an existing line in the pager buffer; this simply means that the
- * input line does not need to be cloned since we alreayd have it. This is
+ * input line does not need to be cloned since we already have it. This is
* typical if we are reindexing the pager buffer.
*
* @param cf The CLI session whose pager we are adding to.
case DO:
case DONT:
/* Expect 3 bytes */
- if (vec_len (input_vector) < 3)
+ if (len < 3)
return -1; /* want more bytes */
consume = 2;
clib_file_t *uf;
int i;
+ /* Validate cli_file_index */
+ if (pool_is_free_index (cm->cli_file_pool, cli_file_index))
+ return;
+
cf = pool_elt_at_index (cm->cli_file_pool, cli_file_index);
uf = pool_elt_at_index (fm->file_pool, cf->clib_file_index);
unix_cli_file_t *cf;
clib_file_t template = { 0 };
vlib_main_t *vm = um->vlib_main;
- vlib_node_t *n;
+ vlib_node_t *n = 0;
u8 *file_desc = 0;
file_desc = format (0, "%s", name);
if (vec_len (cm->unused_cli_process_node_indices) > 0)
{
uword l = vec_len (cm->unused_cli_process_node_indices);
+ int i;
+ vlib_main_t *this_vlib_main;
+ u8 *old_name = 0;
- /* Find node and give it new name. */
- n = vlib_get_node (vm, cm->unused_cli_process_node_indices[l - 1]);
- vec_free (n->name);
- n->name = (u8 *) name;
+ /*
+ * Nodes are bulk-copied, so node name pointers are shared.
+ * Find the cli node in all graph replicas, and give all of them
+ * the same new name.
+ * Then, throw away the old shared name-vector.
+ */
+ for (i = 0; i < vec_len (vlib_mains); i++)
+ {
+ this_vlib_main = vlib_mains[i];
+ if (this_vlib_main == 0)
+ continue;
+ n = vlib_get_node (this_vlib_main,
+ cm->unused_cli_process_node_indices[l - 1]);
+ old_name = n->name;
+ n->name = (u8 *) name;
+ }
+ vec_free (old_name);
vlib_node_set_state (vm, n->index, VLIB_NODE_STATE_POLLING);
};
r.name = name;
+
+ vlib_worker_thread_barrier_sync (vm);
+
vlib_register_node (vm, &r);
vec_free (name);
n = vlib_get_node (vm, r.index);
+ vlib_worker_thread_node_runtime_update ();
+ vlib_worker_thread_barrier_release (vm);
}
pool_get (cm->cli_file_pool, cf);
- memset (cf, 0, sizeof (*cf));
+ clib_memset (cf, 0, sizeof (*cf));
template.read_function = unix_cli_read_ready;
template.write_function = unix_cli_write_ready;
clib_error_t *error;
unix_cli_file_t *cf;
u32 cf_index;
+ int one;
error = clib_socket_accept (s, &client);
if (error)
return error;
+ /* Disable Nagle, ignore any errors doing so eg on PF_LOCAL socket */
+ one = 1;
+ (void) setsockopt (client.fd, IPPROTO_TCP, TCP_NODELAY,
+ (void *) &one, sizeof (one));
+
client_name = (char *) format (0, "%U%c", format_sockaddr, &client.peer, 0);
cf_index = unix_cli_file_add (cm, client_name, client.fd);
if (isatty (STDIN_FILENO) && um->cli_line_mode == 0)
{
/* Capture terminal resize events */
- memset (&sa, 0, sizeof (sa));
+ clib_memset (&sa, 0, sizeof (sa));
sa.sa_handler = unix_cli_resize_interrupt;
if (sigaction (SIGWINCH, &sa, 0) < 0)
clib_panic ("sigaction");
tio = um->tio_stdin;
/* echo off, canonical mode off, ext'd input processing off */
tio.c_lflag &= ~(ECHO | ICANON | IEXTEN);
+ /* disable XON/XOFF, so ^S invokes the history search */
+ tio.c_iflag &= ~(IXON | IXOFF);
tio.c_cc[VMIN] = 1; /* 1 byte at a time */
tio.c_cc[VTIME] = 0; /* no timer */
+ tio.c_cc[VSTOP] = _POSIX_VDISABLE; /* not ^S */
+ tio.c_cc[VSTART] = _POSIX_VDISABLE; /* not ^Q */
tcsetattr (STDIN_FILENO, TCSAFLUSH, &tio);
/* See if we can do ANSI/VT100 output */