Error handling for CLI
Continue, do not exit on read/expand errors Accept -1 error without clicon_err in callbacks / expand C-API: Three-value return of clicon_cliread
This commit is contained in:
parent
f82ce896a9
commit
caef594dbe
4 changed files with 58 additions and 35 deletions
|
|
@ -156,7 +156,6 @@ cli_history_save(clicon_handle h)
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*! Clean and close all state of cli process (but dont exit).
|
||||
* Cannot use h after this
|
||||
* @param[in] h Clixon handle
|
||||
|
|
@ -236,17 +235,22 @@ cli_interactive(clicon_handle h)
|
|||
char *cmd;
|
||||
char *new_mode;
|
||||
cligen_result result;
|
||||
int ret;
|
||||
|
||||
/* Loop through all commands */
|
||||
while(!cligen_exiting(cli_cligen(h))) {
|
||||
new_mode = cli_syntax_mode(h);
|
||||
cmd = NULL;
|
||||
if (clicon_cliread(h, &cmd) < 0)
|
||||
/* Read a CLI string, including expand handling */
|
||||
if ((ret = clicon_cliread(h, &cmd)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
continue;
|
||||
if (cmd == NULL) { /* EOF */
|
||||
cligen_exiting_set(cli_cligen(h), 1);
|
||||
continue;
|
||||
}
|
||||
/* Here errors are handled */
|
||||
if (clicon_parse(h, cmd, &new_mode, &result, NULL) < 0)
|
||||
goto done;
|
||||
/* Why not check result? */
|
||||
|
|
@ -815,7 +819,6 @@ main(int argc,
|
|||
goto done;
|
||||
}
|
||||
|
||||
|
||||
/* Go into event-loop unless -1 command-line */
|
||||
if (!once){
|
||||
retval = cli_interactive(h);
|
||||
|
|
|
|||
|
|
@ -516,8 +516,9 @@ cli_plugin_finish(clicon_handle h)
|
|||
int
|
||||
cli_handler_err(FILE *f)
|
||||
{
|
||||
if (clicon_errno &&
|
||||
(clicon_get_logflags() & CLICON_LOG_STDERR) == 0){
|
||||
if (clicon_errno){
|
||||
/* Check if error is already logged on stderr */
|
||||
if ((clicon_get_logflags() & CLICON_LOG_STDERR) == 0){
|
||||
fprintf(f, "%s: %s", clicon_strerror(clicon_errno), clicon_err_reason);
|
||||
if (clicon_suberrno)
|
||||
fprintf(f, ": %s", strerror(clicon_suberrno));
|
||||
|
|
@ -525,6 +526,7 @@ cli_handler_err(FILE *f)
|
|||
}
|
||||
else
|
||||
fprintf(f, "CLI command error\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -596,7 +598,7 @@ clicon_parse(clicon_handle h,
|
|||
switch (*result) {
|
||||
case CG_EOF: /* eof */
|
||||
case CG_ERROR:
|
||||
fprintf(f, "CLI parse error: %s\n", cmd);
|
||||
fprintf(f, "CLI parse error: %s\n", cmd); // In practice never happens
|
||||
break;
|
||||
case CG_NOMATCH: /* no match */
|
||||
fprintf(f, "CLI syntax error: \"%s\": %s\n", cmd, reason);
|
||||
|
|
@ -741,7 +743,8 @@ cli_prompt_get(clicon_handle h,
|
|||
/*! Read command from CLIgen's cliread() using current syntax mode.
|
||||
* @param[in] h Clicon handle
|
||||
* @param[out] stringp Pointer to command buffer or NULL on EOF
|
||||
* @retval 0 OK
|
||||
* @retval 1 OK
|
||||
* @retval 0 Fail but continue
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
|
|
@ -776,15 +779,22 @@ clicon_cliread(clicon_handle h,
|
|||
}
|
||||
cligen_ph_active_set_byname(cli_cligen(h), mode->csm_name);
|
||||
|
||||
clicon_err_reset();
|
||||
if (cliread(cli_cligen(h), stringp) < 0){
|
||||
clicon_err(OE_FATAL, errno, "CLIgen");
|
||||
cli_handler_err(stdout);
|
||||
if (clicon_suberrno == ESHUTDOWN)
|
||||
goto done;
|
||||
goto fail;
|
||||
}
|
||||
retval = 0;
|
||||
|
||||
retval = 1;
|
||||
done:
|
||||
if (pfmt)
|
||||
free(pfmt);
|
||||
return retval;
|
||||
fail:
|
||||
retval = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -155,6 +155,10 @@ clicon_err_reset(void)
|
|||
}
|
||||
|
||||
/*! Find error category struct given name
|
||||
*
|
||||
* @param[in] category Error category
|
||||
* @retval cec error category callback structs
|
||||
* @retval NULL Not found
|
||||
*/
|
||||
static struct clixon_err_cats *
|
||||
find_category(int category)
|
||||
|
|
@ -181,6 +185,13 @@ find_category(int category)
|
|||
* - Logs to syslog with LOG_ERR
|
||||
* - Set global error variable name clicon_errno
|
||||
* - Set global reason string clicon_err_reason
|
||||
* Typically a call to clicon_err() is followed by a return -1 (or NULL) that signals
|
||||
* a fatal error that fails early and loud.
|
||||
* However there are some cases where such an error does not cause an exit. This includes
|
||||
* CLI operations of callbacks and expand functions. The reason is that user-defined errors
|
||||
* should just signal an error and not terminate. To override this one can set a suberr to
|
||||
* ESHUTDOWN.
|
||||
*
|
||||
* @note: err direction (syslog and/or stderr) controlled by clicon_log_init()
|
||||
*
|
||||
* @param[in] fn Inline function name (when called from clicon_err() macro)
|
||||
|
|
@ -227,7 +238,6 @@ clicon_err_fn(const char *fn,
|
|||
}
|
||||
va_end(args);
|
||||
strncpy(clicon_err_reason, msg, ERR_STRLEN-1);
|
||||
|
||||
/* Check category callbacks as defined in clixon_err_cat_reg */
|
||||
if ((cec = find_category(category)) != NULL &&
|
||||
cec->cec_logfn){
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue