vlib: unix cli - log cli commands one per line
[vpp.git] / src / vlib / unix / cli.c
index 22f56c7..6e566d1 100644 (file)
@@ -293,6 +293,7 @@ typedef enum
   UNIX_CLI_PARSE_ACTION_WORDRIGHT,     /**< Jump cursor to start of right word */
   UNIX_CLI_PARSE_ACTION_ERASELINELEFT, /**< Erase line to left of cursor */
   UNIX_CLI_PARSE_ACTION_ERASELINERIGHT,        /**< Erase line to right & including cursor */
+  UNIX_CLI_PARSE_ACTION_ERASEWORDLEFT, /**< Erase word left */
   UNIX_CLI_PARSE_ACTION_CLEAR,         /**< Clear the terminal */
   UNIX_CLI_PARSE_ACTION_REVSEARCH,     /**< Search backwards in command history */
   UNIX_CLI_PARSE_ACTION_FWDSEARCH,     /**< Search forwards in command history */
@@ -359,6 +360,7 @@ static unix_cli_parse_actions_t unix_cli_parse_strings[] = {
   _(CTL ('D'), UNIX_CLI_PARSE_ACTION_ERASERIGHT),
   _(CTL ('U'), UNIX_CLI_PARSE_ACTION_ERASELINELEFT),
   _(CTL ('K'), UNIX_CLI_PARSE_ACTION_ERASELINERIGHT),
+  _(CTL ('W'), UNIX_CLI_PARSE_ACTION_ERASEWORDLEFT),
   _(CTL ('Y'), UNIX_CLI_PARSE_ACTION_YANK),
   _(CTL ('L'), UNIX_CLI_PARSE_ACTION_CLEAR),
   _(ESC "b", UNIX_CLI_PARSE_ACTION_WORDLEFT),  /* Alt-B */
@@ -1616,6 +1618,51 @@ unix_cli_line_process_one (unix_cli_main_t * cm,
       cf->search_mode = 0;
       break;
 
+    case UNIX_CLI_PARSE_ACTION_ERASEWORDLEFT:
+      /* calculate num of caracter to be erased */
+      delta = 0;
+      while (cf->cursor > delta
+            && cf->current_command[cf->cursor - delta - 1] == ' ')
+       delta++;
+      while (cf->cursor > delta
+            && cf->current_command[cf->cursor - delta - 1] != ' ')
+       delta++;
+
+      if (vec_len (cf->current_command))
+       {
+         if (cf->cursor > 0)
+           {
+             /* move cursor left delta times */
+             for (j = delta; j > 0; j--, cf->cursor--)
+               unix_vlib_cli_output_cursor_left (cf, uf);
+             save = cf->current_command + cf->cursor;
+
+             /* redraw remainder of line */
+             memmove (cf->current_command + cf->cursor,
+                      cf->current_command + cf->cursor + delta,
+                      _vec_len (cf->current_command) - cf->cursor - delta);
+             unix_vlib_cli_output_cooked (cf, uf,
+                                          cf->current_command + cf->cursor,
+                                          _vec_len (cf->current_command) -
+                                          cf->cursor);
+             cf->cursor += _vec_len (cf->current_command) - cf->cursor;
+
+             /* print delta amount of blank spaces,
+              * then finally fix the cursor position */
+             for (j = delta; j > 0; j--, cf->cursor--)
+               unix_vlib_cli_output_cursor_left (cf, uf);
+             for (j = delta; j > 0; j--, cf->cursor++)
+               unix_vlib_cli_output_cooked (cf, uf, (u8 *) " ", 1);
+             for (; (cf->current_command + cf->cursor) > save; cf->cursor--)
+               unix_vlib_cli_output_cursor_left (cf, uf);
+             _vec_len (cf->current_command) -= delta;
+           }
+       }
+      cf->search_mode = 0;
+      cf->excursion = 0;
+      vec_reset_length (cf->search_key);
+      break;
+
     case UNIX_CLI_PARSE_ACTION_LEFT:
       if (cf->cursor > 0)
        {
@@ -2510,6 +2557,8 @@ more:
                   format_timeval, 0 /* current bat-time */ ,
                   0 /* current bat-format */ ,
                   cli_file_index, cf->current_command);
+      if (cf->current_command[vec_len (cf->current_command) - 1] != '\n')
+       lv = format (lv, "\n");
       int rv __attribute__ ((unused)) = write (um->log_fd, lv, vec_len (lv));
     }
 
@@ -2817,7 +2866,7 @@ unix_cli_file_add (unix_cli_main_t * cm, char *name, int fd)
       static vlib_node_registration_t r = {
        .function = unix_cli_process,
        .type = VLIB_NODE_TYPE_PROCESS,
-       .process_log2_n_stack_bytes = 16,
+       .process_log2_n_stack_bytes = 18,
       };
 
       r.name = name;
@@ -3042,9 +3091,11 @@ unix_cli_config (vlib_main_t * vm, unformat_input_t * input)
            clib_panic ("sigaction");
 
          /* Retrieve the current terminal size */
-         ioctl (STDIN_FILENO, TIOCGWINSZ, &ws);
-         cf->width = ws.ws_col;
-         cf->height = ws.ws_row;
+         if (ioctl (STDIN_FILENO, TIOCGWINSZ, &ws) == 0)
+           {
+             cf->width = ws.ws_col;
+             cf->height = ws.ws_row;
+           }
 
          if (cf->width == 0 || cf->height == 0)
            {
@@ -3281,7 +3332,7 @@ unix_cli_exec (vlib_main_t * vm,
   unformat_free (&sub_input);
 
 done:
-  if (fd > 0)
+  if (fd >= 0)
     close (fd);
   vec_free (file_name);
 
@@ -3800,6 +3851,46 @@ VLIB_CLI_COMMAND (cli_unix_cli_set_terminal_ansi, static) = {
 };
 /* *INDENT-ON* */
 
+
+#define MAX_CLI_WAIT 86400
+/** CLI command to wait <sec> seconds. Useful for exec script. */
+static clib_error_t *
+unix_wait_cmd (vlib_main_t * vm,
+              unformat_input_t * input, vlib_cli_command_t * cmd)
+{
+  unformat_input_t _line_input, *line_input = &_line_input;
+  f64 sec = 1.0;
+
+  if (!unformat_user (input, unformat_line_input, line_input))
+    return 0;
+
+  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (line_input, "%f", &sec))
+       ;
+      else
+       return clib_error_return (0, "unknown parameter: `%U`",
+                                 format_unformat_error, input);
+    }
+
+  if (sec <= 0 || sec > MAX_CLI_WAIT || floor (sec * 1000) / 1000 != sec)
+    return clib_error_return (0,
+                             "<sec> must be a positive value and less than 86400 (one day) with no more than msec precision.");
+
+  vlib_process_wait_for_event_or_clock (vm, sec);
+  vlib_cli_output (vm, "waited %.3f sec.", sec);
+
+  unformat_free (line_input);
+  return 0;
+}
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (cli_unix_wait_cmd, static) = {
+  .path = "wait",
+  .short_help = "wait <sec>",
+  .function = unix_wait_cmd,
+};
+/* *INDENT-ON* */
+
 static clib_error_t *
 unix_cli_init (vlib_main_t * vm)
 {